EF Include语句中的表达式<tdelegate>

时间:2017-06-28 12:41:51

标签: c# entity-framework linq

你好,所以我试图让一些更动态,我说我希望能够传入一个表达式,其中包含我试图包含的实体。当我试图这样做时,我不断收到错误消息:

  

Include路径表达式必须引用在类型上定义的导航属性。使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性。

我搜索了这个错误,发现他们正在做我可以开始工作的事情:

context.Contacts.Include(contact=>contact.PhoneNumber)

我想要做的是:

  Func<IEntity, IEntity> func = (contact) => ((Contact)contact).PhoneNumber;
  Expression<Func<IEntity, IEntity>> expression = (contact)=> func(contact);
  context.Contacts.Include(expression);

有人可以说明我做错了什么以及为什么?

public interface IEntity
{
    int Id { get; set; }
}

public class Contact:IEntity
{
    public int Id {get;set;}
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int PhoneNumberId { get; set; }
    public PhoneNumber PhoneNumber { get; set; }
}

public class PhoneNumber:IEntity
{
    public int Id { get; set; }
    public string Number { get; set; }
}

更新 我有一个存储库类,它查看类的类型并使用反射来获取正确的DbSet并返回IQueryable。

  public IQueryable Get(IEntity t)
  { 
     var setMethod =  typeof(DbContext)
                          .GetMethod(nameof(DbContext.Set))
                          .MakeGenericMethod(t.getType());
     var query = (IQueryable)setMethod.Invoke(db, null);
     var results = query... 
  }

我有一个表控件,可以使用typeRepository获取正确的数据。所以我试图能够将实体包含在该表中。

2 个答案:

答案 0 :(得分:2)

如果您没有泛型类型参数,但只有简单的Type参数,则最好使用EF提供的非通用DbContextIQueryable服务。

首先,您不需要反思 - DbContext提供带有Set参数的非通用Type方法:

public virtual DbSet Set(Type entityType)

对于Include,您只需使用带有Include参数的非通用string扩展方法:

public static IQueryable Include(this IQueryable source, string path)

所以有问题的方法可以这样实现:

IQueryable query = db.Set(t.GetType());
if (t is Contact)
    query = query.Include(nameof(Contact.PhoneNumber)); 

不是最好的OOP实践,但适用于所选设计。

答案 1 :(得分:-1)

我相信您的问题与您分配给Func的委托类型有关。 IE:Func<IEntity, IEntity> func 在这种情况下,IEntity没有定义类型IEntity

的导航属性

尝试为您的实施分配具体类型

Func<Contact, PhoneNumber> func