抽象DomainCollectionView(Entity Framework)代码转换成自己的服务(MVVM Silverlight4)

时间:2011-03-08 19:22:19

标签: c# silverlight entity-framework mvvm

我有一个VM类,用于将视图连接到我的ADO.NET实体数据模型,使用P_BUDGET类。这工作正常,获取我的数据,使一切都很漂亮。我有大约15-20个页面都将基于与此相同的结构,除了EntityType(P_BUDGET,P_ACCOUNT,P_CIRCUIT等等)之外,代码几乎完全相同。我觉得应该有一种方法来抽象出来,但我尝试过,并且悲惨地失败了!我也觉得我应该能够使用一个视图,一个视图模型,只需交换绑定到GV的实体......我只是无法找到一种方法来改变整个视图模型的类型。

感谢您的帮助,

斯科特

public class TestViewModel : ViewModelBase
{
    private readonly ODADomainContext _context = new ODADomainContext();
    private readonly DomainCollectionView<P_BUDGET> _view;
    private readonly DomainCollectionViewLoader<P_BUDGET> _loader;
    private readonly EntityList<P_BUDGET> _source;
    private bool _isGridEnabled;
    /// <summary>
    /// Initializes a new instance of the TestViewModel class.
    /// </summary>
    public TestViewModel()
    {
        this._source = new EntityList<P_BUDGET>(this._context.P_BUDGETs);
        this._loader = new DomainCollectionViewLoader<P_BUDGET>(
             this.LoadSampleEntities,
             this.OnLoadSampleEntitiesCompleted);
        this._view = new DomainCollectionView<P_BUDGET>(this._loader, this._source);

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

        using (this.CollectionView.DeferRefresh())
        {
            this._view.PageSize = 10;
            this._view.MoveToFirstPage();
        }
    }
    #region View Properties

    public bool IsGridEnabled
    {
        get
        {
            return this._isGridEnabled;
        }

        private set
        {
            if (this._isGridEnabled != value)
            {
                this._isGridEnabled = value;
                this.RaisePropertyChanged("IsGridEnabled");
            }
        }
    }

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

    #endregion

    private LoadOperation<P_BUDGET> LoadSampleEntities()
    {
        this.IsGridEnabled = false;

        return this._context.Load(
             this._context.GetBudgetsQuery());
    }

    private void OnLoadSampleEntitiesCompleted(LoadOperation<P_BUDGET> op)
    {
        this.IsGridEnabled = true;

        if (op.HasError)
        {
            // TODO: handle errors
            _view.PageSize = 0;
            op.MarkErrorAsHandled();
        }
        else if (!op.IsCanceled)
        {
            this._source.Source = op.Entities;
            _view.PageSize = 10;
            this._view.MoveToFirstPage();
            if (op.TotalEntityCount != -1)
            {
                this._view.SetTotalItemCount(op.TotalEntityCount);
            }
        }
    }
    ////public override void Cleanup()
    ////{
    ////    // Clean own resources if needed

    ////    base.Cleanup();
    ////}
}

1 个答案:

答案 0 :(得分:0)

尝试这样的事情。这没有经过测试(很明显),甚至没有被遵守。这也假定EntityTypes(P_BUDGET,P_ACCOUNT,P_CIRCUIT等)不是POCO。

public class TestViewModel<TEntity> : ViewModelBase
{
    private readonly ODADomainContext _context = new ODADomainContext();
    private readonly DomainCollectionView<TEntity> _view;
    private readonly DomainCollectionViewLoader<TEntity> _loader;
    private readonly EntityList<TEntity> _source;
    private bool _isGridEnabled;
    /// <summary>
    /// Initializes a new instance of the TestViewModel class.
    /// </summary>
    public TestViewModel()
    {
        this._source = new EntityList<TEntity>(this._context.GetEntitySet<TEntity>);
        this._loader = new DomainCollectionViewLoader<TEntity>(
             this.LoadSampleEntities,
             this.OnLoadSampleEntitiesCompleted);
        this._view = new DomainCollectionView<TEntity>(this._loader, this._source);

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

        using (this.CollectionView.DeferRefresh())
        {
            this._view.PageSize = 10;
            this._view.MoveToFirstPage();
        }
    }
    #region View Properties

    public bool IsGridEnabled
    {
        get
        {
            return this._isGridEnabled;
        }

        private set
        {
            if (this._isGridEnabled != value)
            {
                this._isGridEnabled = value;
                this.RaisePropertyChanged("IsGridEnabled");
            }
        }
    }

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

    #endregion

    private LoadOperation<TEntity> LoadSampleEntities()
    {
        this.IsGridEnabled = false;

        return this._context.Load(
             this._context.GetBudgetsQuery());
    }

    private void OnLoadSampleEntitiesCompleted(LoadOperation<TEntity> op)
    {
        this.IsGridEnabled = true;

        if (op.HasError)
        {
            // TODO: handle errors
            _view.PageSize = 0;
            op.MarkErrorAsHandled();
        }
        else if (!op.IsCanceled)
        {
            this._source.Source = op.Entities;
            _view.PageSize = 10;
            this._view.MoveToFirstPage();
            if (op.TotalEntityCount != -1)
            {
                this._view.SetTotalItemCount(op.TotalEntityCount);
            }
        }
    }
    ////public override void Cleanup()
    ////{
    ////    // Clean own resources if needed

    ////    base.Cleanup();
    ////}
}

// http://blog.zoolutions.se/post/2010/04/05/Generic-Repository-for-Entity-Framework-for-Pluralized-Entity-Set.aspx

public static class ObjectContextExtensions
{
    internal static EntitySetBase GetEntitySet<TEntity>(this ObjectContext context)
    {
        EntityContainer container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
        Type baseType = GetBaseType(typeof(TEntity));
        EntitySetBase entitySet = container.BaseEntitySets
            .Where(item => item.ElementType.Name.Equals(baseType.Name))
            .FirstOrDefault();

        return entitySet;
    }

    private static Type GetBaseType(Type type)
    {
        var baseType = type.BaseType;
        if (baseType != null && baseType != typeof(EntityObject))
        {
            return GetBaseType(type.BaseType);
        }
        return type;
    }
}