支持不同Entity的DomainCollectionView模版

用于Silverlight使用RiaService获取服务器端分页数据

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows.Input;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.ComponentModel;
using System.ServiceModel.DomainServices.Client;
using System.ServiceModel.DomainServices;
using Microsoft.Windows.Data.DomainServices;
using ZL.Push.Web;


namespace ZL.Push.Web
{
    public sealed partial class ZLPushContext : DomainContext
    {
        public EntityQuery<TEntity> GetQuery<TEntity>(ref string entityName) where TEntity : Entity
        {
            this.ValidateMethod("Get" + entityName + "Query", null);
            return base.CreateQuery<TEntity>("Get" + entityName, null, false, true);
        }
    }
}

namespace ZL.Push
{
    public class ZLViewModel<TEntity> : INotifyPropertyChanged where TEntity : Entity
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        private readonly ZLPushContext _context = null;
        private readonly DomainCollectionView<TEntity> _view;
        private readonly DomainCollectionViewLoader<TEntity> _loader;
        private readonly EntityList<TEntity> _source;
        public EntityList<TEntity> source
        {
            get { return _source; }
        }

        private bool _canLoad = false;
        private bool _refresh_current = false;
        private string _searchText = string.Empty;
        private string _entityName = string.Empty;

        #region View Properties
        public Expression<Func<TEntity, bool>> lambda { get; set; }
        public bool CanLoad
        {
            get { return this._canLoad; }
            set
            {
                if (this._canLoad != value)
                {
                    this._canLoad = value;
                    this.RaisePropertyChanged("CanLoad");
                }
            }
        }

        public ICollectionView CollectionView
        {
            get { return this._view; }
        }
        #endregion


        public ZLViewModel(ZLPushContext context, string entityName, bool refresh_current = true)
        {
            lambda = null;

            _context = context;
            _entityName = entityName.Substring(0, 1).ToUpper() + entityName.Substring(1);
            _refresh_current = refresh_current;

            this._source = new EntityList<TEntity>(this._context.EntityContainer.GetEntitySet<TEntity>());
            this._loader = new DomainCollectionViewLoader<TEntity>(
                this.LoadEntities,
                this.OnLoadEntitiesCompleted);
            this._view = new DomainCollectionView<TEntity>(this._loader, this._source);

            INotifyCollectionChanged notifyingSortDescriptions =(INotifyCollectionChanged)this.CollectionView.SortDescriptions;
            notifyingSortDescriptions.CollectionChanged += (sender, e) => this._view.MoveToFirstPage();
        }

        public void OnSearch()
        {
            // This makes sure we refresh even if we're already on the first page
            using (this._view.DeferRefresh())
            {
                // This will lead us to re-query for the total count
                this._view.SetTotalItemCount(-1);
                this._view.MoveToFirstPage();
            }
        }

        public void Clear()
        {
            this._source.Source = null;
        }

        public void AddNoSubmit(ref TEntity tbl)
        {
            this._source.Add(tbl);
        }

        public void Add(TEntity tbl, Action<bool> callback = null)
        {
            this._source.Add(tbl);

            this._context.SubmitChanges((op) =>
            {
                if (op.HasError)
                {
                    //恢复
                    this._source.Remove(tbl);

                    op.MarkErrorAsHandled();
                    System.Windows.MessageBox.Show(op.Error.Message);
                }
                if (callback != null)
                {
                    callback(!op.HasError);
                }
            }, false);
        }

        public void Edit(Action<bool> callback = null)
        {
            this._context.SubmitChanges((op) =>
            {
                if (op.HasError)
                {
                    op.MarkErrorAsHandled();
                    System.Windows.MessageBox.Show(op.Error.Message);
                }
                if (callback != null)
                {
                    callback(!op.HasError);
                }
            }, false);
        }

        public void DeleteNoSubmit(TEntity tbl)
        {
            this._source.Remove(tbl);
        }

        public void Delete(TEntity tbl, Action<bool> callback = null)
        {
            int index = this._source.IndexOf(tbl);
            this._source.RemoveAt(index);
            this._context.SubmitChanges((op) =>
            {
                if (op.HasError)
                {
                    // 恢复
                    this._source.Insert(index, tbl);

                    op.MarkErrorAsHandled();
                    System.Windows.MessageBox.Show(op.Error.Message);
                }

                if (callback != null)
                {
                    callback(!op.HasError);
                }
            }, false);
        }

        private LoadOperation<TEntity> LoadEntities()
        {
            this.CanLoad = false;

            EntityQuery<TEntity> query = this._context.GetQuery<TEntity>(ref _entityName);
            if (lambda != null)
            {
                query = query.Where(lambda);
            }

            // 如果不order by id,下面的SortAndPageBy会报错
            var param = Expression.Parameter(typeof(TEntity), "c");
            var body = Expression.PropertyOrField(param, "id");
            var sortExpression = Expression.Lambda<Func<TEntity, Int32>>(body, param);
            query = query.OrderBy(sortExpression);
            if (_refresh_current)
            {
                return this._context.Load<TEntity>(query.SortAndPageBy(this._view), LoadBehavior.RefreshCurrent, false);
            }
            else
            {
                return this._context.Load<TEntity>(query.SortAndPageBy(this._view));
            }
        }

        private void OnLoadEntitiesCompleted(LoadOperation<TEntity> op)
        {
            this.CanLoad = true;
           
            if (op.HasError)
            {
                op.MarkErrorAsHandled();
                System.Windows.MessageBox.Show(op.Error.Message);
            }
            else if (!op.IsCanceled)
            {
                this._source.Source = op.Entities;
                if (op.TotalEntityCount != -1)
                {
                    this._view.SetTotalItemCount(op.TotalEntityCount);
                }
            }
        }
    }
}

使用示例代码:
a) 绑定到datagrid并检索
              ZLPushContext _context = new ZLPushContext();
            ZLViewModel<tbl_metadata> _vm = new ZLViewModel<tbl_metadata>(_context, "tbl_metadata");

            _datagrid.DataContext = _vm;
            _datapager.DataContext = _vm;

            _vm.lambda = _create_lamda();
            _vm.OnSearch();

b) 添加entity
            tbl_metadata tbl = new tbl_metadata();
            _vm.Add(tbl, (result) =>
                    {
                        if (result)
                        {
                        }
                    } );

你可能感兴趣的:(silverlight,LINQ)