根據Lambda表達式字典應用Include和ThenInclude

c# entity-framework entity-framework-core

我有一些Entity Framework 7(Core)實體:

public class Person {
   public virtual Address Address { get; set; }
   public virtual ICollection<Hobby> Hobbies { get; set; }
}

public class Address {
   public String Street { get; set; }
   public virtual Country Country { get; set; }
}

我有一個字符串數組如下:

String[] entities = new String[] { "Hobbies", "Address.Country" }

鑑於這個字符串數組我得到:

context.Persons
  .Include(x => x.Hobbies)
  .Include(x => x.Address).ThenInclude(x => x.Country);

在EF6中我可以做類似的事情:

context.Persons.Include(entities[0]).Include(entities[1]);

但在EF7 Include中不允許使用字符串。我創建了字典:

private readonly Dictionary<String, LambdaExpression> _properties = new Dictionary<String, LambdaExpression>();

哪個會有類似的東西:

x => x.Hobbies is for "Hobbies"
x => x.Address.Country is for "Address.Country"     

我有擴展名:

public static IQueryable<T> Include<T>(this IQueryable<T> source, Dictionary<String, LambdaExpression> properties) {
}

我需要給詞典應用以下內容:

  1. 對於“x => x.Hobbies”,只需:

     source.Include(x => x.Hobbies);
    
  2. 如果表達式類似於“x => x.Address.Country”,則添加:

     source.Include(x => x.Address).ThenInclude(x => x.Country);
    

可以這樣做嗎?

一般承認的答案

不確定ThenInclude()和EF 7,但你可以在你的存儲庫中做這樣的事情(用EF 6測試):

public MyEntity GetMyEntity_EagerlyLoad(DbContext context, int id, params Expression<Func<MyEntity, object>>[] propertiesToLoad)
{
    var q = context.MyEntities.Where(m => m.ID == id);

    foreach (var prop in propertiesToLoad)
        q = q.Include(prop);

    return q.SingleOrDefault();
}

然後你可以像這樣調用它:

repo.GetMyEntity_EagerlyLoad(context, id, m => m.Property1, m => m.Property2, m => m.Property1.NestedProperty)


編輯 :還有另一種方法,使用投影進行EF的急切加載。您可以像這樣執行通用存儲庫方法:

public MyEntity GetMyEntity_EagerlyLoad<T>(DbContext context, int id, Expression<Func<MyEntity, T>> loadingProjection, Func<T, MyEntity> resultProjection)
{
    var q = context.MyEntities.Where(m => m.ID == id);

    return q.Select(loadingProjection).AsEnumerable().Select(resultProjection).SingleOrDefault();
}

然後使用要加載的屬性和希望方法返回的實體調用它:

repo.GetMyEntity_EagerlyLoad(context, id, m => new { myEntity = m, m.Property1, m.Property2, m.Property1.NestedProperty }, m => m.myEntity)


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因