你好,所以我试图让一些更动态,我说我希望能够传入一个表达式,其中包含我试图包含的实体。当我试图这样做时,我不断收到错误消息:
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获取正确的数据。所以我试图能够将实体包含在该表中。
答案 0 :(得分:2)
如果您没有泛型类型参数,但只有简单的Type
参数,则最好使用EF提供的非通用DbContext
和IQueryable
服务。
首先,您不需要反思 - 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