开发者

Abstract DomainCollectionView (Entity Framework) code into its own service (MVVM Silverlight4)

开发者 https://www.devze.com 2023-02-16 02:04 出处:网络
I\'ve got a VM class below that\'s being used to wire up a view to my ADO.NET Entity Data Model, utilizing a P_BUDGET class. This works fine, gets my data, makes everything pretty. I have about 15-20

I've got a VM class below that's being used to wire up a view to my ADO.NET Entity Data Model, utilizing a P_BUDGET class. This works fine, gets my data, makes everything pretty. I have about 15-20 pages that are all going to be based on the same structure as this, and the code is going开发者_StackOverflow社区 to be virtually identical except for the EntityType (P_BUDGET, P_ACCOUNT, P_CIRCUIT, etc etc). I feel like there should be a way to abstract this out, but I tried, and failed miserably! I also feel like I should be able to use one view, one viewmodel, and just swap out the entities binding to the GV... I just haven't been able to find a way to variablize the type, which permeates the entire viewmodel.

Appreciate your help,

Scott

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();
    ////}
}


Try something like this. This is not tested (obviously), not even complied. This also assumes that the EntityTypes (P_BUDGET, P_ACCOUNT, P_CIRCUIT etc.) are not POCOs.

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;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号