C#Entity Framework Generic class - >重新加载所有子实体

时间:2018-03-29 07:36:37

标签: c# entity-framework-6 generic-programming

我目前有一个多对一关系层次结构数据库tblProjects-> tblLines-> tblGroups-> tblStations等。还有一个Entity框架6模型。

这些实体框架类都实现了基类“tblBase”:

  public abstract class TblBase : INotifyPropertyChanged
{
    private int _id;
    public int ID
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
            NotifyPropertyChanged();
        }
    }

    private Nullable<int> _coid;
    public Nullable<int> COID
    {
        get
        {
            NotifyPropertyChanged();
            return _coid;
        }
        set
        {
            _coid = value;
            NotifyPropertyChanged();
        }
    }

    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
            NotifyPropertyChanged();
        }
    }

我有一个树视图,允许我选择任何节点作为父类型,目前我有一个方法,允许我重新加载所有子实体。

我想看看如何将它变成通用的:

      private async static Task<bool> RefreshLinesAsync(LocalUser ThisUser, ProjectEntities DBContext, object Entity)
    {
        List<object> NonExistingNodes = new List<object>();
        var bContinue = false;
        var PassedEntity = Entity as TblBase;

        //Scan through all DB child entities and reload their DB values
       foreach (var SubEntity in DBContext.tblLines.Where(x => x.ProjectID == PassedEntity.ID).ToList())
        {
            await DBContext.Entry(SubEntity).ReloadAsync().ContinueWith(x =>
            {
                if (!x.IsFaulted)
                {
                    if ((SubEntity.COID.GetValueOrDefault() != 0) && (SubEntity.COID.GetValueOrDefault() != ThisUser.ID))
                        NotifyCOIDConflict(SubEntity, new CheckedOutArgs()
                        {
                            ConflictCOID = SubEntity.COID.GetValueOrDefault()
                        });
                    bContinue = true; 
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
            if (bContinue)
                //Continue to child entities method
                await RefreshGroupsAsync(ThisUser, DBContext, SubEntity);
        }
        return true;
    }

    private async static Task<bool> RefreshGroupsAsync(LocalUser ThisUser, ProjectEntities DBContext, object Entity)
    {
        List<object> NonExistingNodes = new List<object>();

        var bContinue = false;
        var PassedEntity = Entity as TblBase;

        foreach (var SubEntity in DBContext.tblGroups.Where(x => x.LineID == PassedEntity.ID).ToList())
        {
            await DBContext.Entry(SubEntity).ReloadAsync().ContinueWith(x =>
            {
                if (!x.IsFaulted)
                {
                    if ((SubEntity.COID.GetValueOrDefault() != 0) && (SubEntity.COID.GetValueOrDefault() != ThisUser.ID))
                        NotifyCOIDConflict(SubEntity, new CheckedOutArgs()
                        {
                            ConflictCOID = SubEntity.COID.GetValueOrDefault()
                        });
                    bContinue = true;
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
            if (bContinue)
                await RefreshStationsAsync(ThisUser,DBContext, SubEntity);
        }
        return true;
    }

我能看到的唯一有用的方法是Set(),虽然它没有提供Where()方法,这是至关重要的,因为我不想检索整个表。

1 个答案:

答案 0 :(得分:1)

您可以使您的功能通用。他们可能喜欢这个:

private async static Task<bool> RefreshLinesAsync<TEntity>(LocalUser ThisUser, ProjectEntities DBContext, TEntity Entity) where TEntity : TblBase
{
    List<TEntity> NonExistingNodes = new List<TEntity>();
    var bContinue = false;
    var PassedEntity = Entity as TblBase;

    foreach (var SubEntity in DBContext.Set<TEntity>().Where(x => (x as TblBase).ProjectID == PassedEntity.ID).ToList()) {
       //Your other code here...
    }
}

函数定义中的where子句,确保只能使用TblBase的子类调用此方法。

编辑:

我忘了提到你需要在foreach循环中将SubEntity转换为TblBase才能使用它...

编辑(回复评论):

如果需要从实体中获取所有TblBase子类,如果将它们保存在单独的表中,则不能使您的函数如此通用:当您必须添加更多子类时,它将变得难以实现。

我建议您通过Table Per Hierarchy使用单个表(请参阅MSDN中的this文章)将TblBase从抽象类更改为具体类,然后您可以通过这种方式获取所有这些:

 var allSubClassEntities = DBContext.Set<TblBase>();