C# EF 5.0-加载T的集合

C# EF 5.0-加载T的集合,c#,entity-framework,C#,Entity Framework,我想写以下更抽象的代码 private void LoadRelatedData(TabAccount tabAccount) { if (ConxCore.Instance.EntityModel.Entry(tabAccount).Collection(x => x.TabAccountLangs).IsLoaded == false) { var list = (from x in ConxCore.Instance.EntityModel.TabAc

我想写以下更抽象的代码

private void LoadRelatedData(TabAccount tabAccount)
{
    if (ConxCore.Instance.EntityModel.Entry(tabAccount).Collection(x => x.TabAccountLangs).IsLoaded == false)
    {
        var list = (from x in ConxCore.Instance.EntityModel.TabAccounts
            from y in x.TabAccountLangs
            select y).ToList();
    }
}
我想抽象的部分如下:

  • .Entry(tabAccount)->应使用每个EntitySet

  • x=>x.TabAccountLangs->应该使用我在调用方法时指定的属性(可能是表达式)

  • 从x…TabAccounts->应该从调用该方法的EntitySet加载数据库集

  • x.TabAccountLangs中y的应该是上面的属性

  • 关于抽象,我只想避免一遍又一遍地复制/粘贴此代码,只需更改上面提到的4点,我很高兴能够使用给定的参数调用此方法,其余的由该方法完成

    因此,不是:

    private void LoadRelatedData(TabAccount tabAccount)
    {
        if (ConxCore.Instance.EntityModel.Entry(tabAccount).Collection(x => x.TabAccountLangs).IsLoaded == false)
        {
            var list = (from x in ConxCore.Instance.EntityModel.TabAccounts
                from y in x.TabAccountLangs
                select y).ToList();
        }
    }
    
    private void LoadRelatedData(TabElement tabElement)
    {
        if (ConxCore.Instance.EntityModel.Entry(tabElement).Collection(x => x.TabElementLangs).IsLoaded == false)
        {
            var list = (from x in ConxCore.Instance.EntityModel.TabElements
                from y in x.TabElementLangs
                select y).ToList();
        }
    }
    
    类似这样的内容(仅伪代码):

    并将此方法称为:

    LoadRelatedData(tabAccount, TabAccountLangs, TabAccounts);
    LoadRelatedData(tabElement, TabElementLangs, TabElements);
    
    希望你能帮助我。提前谢谢

    using System.Data.Entity; // For the Include extension method.
    
    private void LoadRelatedData<TEntity, TRelated>(TEntity entity, Expression<Func<TEntity, ICollection<TRelated>> navigationProperty)
        where TEntity : class
        where TRelated : class
    {
        if (!ConxCore.Instance.EntityModel.Entry(entity).Collection(navigationProperty).IsLoaded) 
        {
            var list = ConxCore.Instance.EntityModel.Set<TEntity>().Include(navigationProperty).ToList();
        }
    }
    
    但是,您知道这样的调用将加载任何x的所有相关数据吗?也就是说,您可能会以非特别优化的方式加载大量数据。如果只想加载单个实体的相关数据,则可以从
    collection
    调用返回的对象加载集合:

    private void LoadRelatedDataOfSingleObject<TEntity, TRelated>(TEntity entity, Expression<Func<TEntity, ICollection<TRelated>> navigationProperty)
        where TEntity : class
        where TRelated : class
    {
        var collectionEntry = ConxCore.Instance.EntityModel.Entry(entity).Collection(navigationProperty);
        if (!collectionEntry.IsLoaded) collectionEntry.Load();
    }
    

    private void LoadRelatedDataOfSingleObject(TEntity entity,Expression感谢您的回答。很遗憾,我无法运行第一个方法,出现以下编译错误:方法'System.Linq.Queryable.SelectMany(System.Linq.IQueryable,System.Linq.Expressions.Expression)的类型参数'无法从用法中推断。请尝试显式指定类型参数。它不允许我指定.SelectMany.:(好的,通过将代码更改为:…SelectMany(navigationProperty.Compile()).ToList();该.Compile()修复了该方法)缺少,现在工作正常。遗憾的是,这不会更新条目的.IsLoaded属性,您知道这样做的方法吗,无需在每个实体上调用load,也无需include?@RandRandom:不要使用
    Compile()
    在这种情况下-您可能会运行大量查询。取而代之的是,使用我上次编辑的代码。其次,如果您希望更新
    .IsLoaded
    ,我认为调用
    Select
    而不是
    SelectMany
    会起作用。不调用Select没有改变任何东西,此代码仍然会每次运行,并且if(…孤岛)没什么区别,有什么传统的想法吗?
    LoadRelatedData(tabAccount, ta => ta.TabAccountLangs);
    LoadRelatedData(tabElement, te => te.TabElementLangs);
    
    private void LoadRelatedDataOfSingleObject<TEntity, TRelated>(TEntity entity, Expression<Func<TEntity, ICollection<TRelated>> navigationProperty)
        where TEntity : class
        where TRelated : class
    {
        var collectionEntry = ConxCore.Instance.EntityModel.Entry(entity).Collection(navigationProperty);
        if (!collectionEntry.IsLoaded) collectionEntry.Load();
    }