简体   繁体   English

使用实体框架转换为IQueryable时为空值

[英]Null Value when converting to IQueryable with Entity Framework

I'm working with EF5 and I have a generic repository with a GetById method that can receive the include properties wanted like this one: 我正在使用EF5,我有一个带有GetById方法的通用存储库,该方法可以接收这样的include属性:

public virtual T GetByIdIncluding(long id, params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable  <T> query = DbContext.Set<T>().Find(id) as IQueryable<T>;

    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    }

    return query.FirstOrDefault();
}

DbContext.Set<T>().Find(id) return the correct object, but when I cast it with as IQueryable then the value of variable query becomes null. DbContext.Set<T>().Find(id)返回正确的对象,但是当我将其DbContext.Set<T>().Find(id)为IQueryable时,变量query的值将变为null。

Why? 为什么? How can I select only the entity with the Id sent by parameter and all the includings sent by parameter? 如何仅选择由参数发送的ID和由参数发送的所有包含内容的实体?

Example of usage: 用法示例:

var houses = Uow.Types.GetByIdIncluding(id, tt => tt.Houses);

Thanks in advance! 提前致谢! Guillermo 吉列尔莫

DbContext.Set<T>().Find(id) returns single entity. DbContext.Set<T>().Find(id)返回单个实体。

IQueryable<T> is a DbContext.Set<T>() . IQueryable<T>DbContext.Set<T>()


You can't include some properties after you selected single entity by id. 通过ID选择单个实体后,您将无法包含某些属性。 Also you can't use DbSet<T>.Find after you included some properties, because result will be IQueryable<T> . 同样,您不能使用DbSet<T>.Find在包含一些属性之后DbSet<T>.Find ,因为结果将是IQueryable<T> What you can do - include properties and filter result by id later: 您可以做什么-稍后包含属性并按ID过滤结果:

public static IQueryable<T> Including(
                          params Expression<Func<T, object>>[] includeProperties)
{            
    IQueryable<T> query = DbContext.Set<T>();

    foreach (var includeProperty in includeProperties)    
        query = query.Include(includeProperty);    

    return query;
}

And later: 然后:

var types = Uow.Types.Including(tt => tt.Houses)
                     .SingleOrDefault(tt => tt.Id == id);

Also you can create method GetByIdIncluding in your concrete repository classes (not in generic repository): 您还可以在具体的存储库类中(而不是在通用存储库中)创建方法GetByIdIncluding

public static Foo GetByIdIncluding(long id, 
                 params Expression<Func<Foo, object>>[] includeProperties)
{
    return Including(includeProperties).SingleOrDefault(f => f.Id == id);
}

BTW consider using lazy-loading (it's enabled by default). 顺便说一句,请考虑使用延迟加载(默认情况下启用)。

http://msdn.microsoft.com/en-us/library/gg696418%28v=vs.103%29.aspx DbSet.Find method returns an entity, not an IQueryable of your entity. http://msdn.microsoft.com/zh-cn/library/gg696418%28v=vs.103%29.aspx DbSet.Find方法返回一个实体,而不是该实体的IQueryable Try setting the Include on the Set before calling the Find method. 尝试在调用Find方法之前在Set上设置Include。

You need to move the Find to after the loop: 您需要在循环后将“ Find移动到:

public virtual T GetByIdIncluding(long id, params Expression<Func<T, object>>[] includeProperties)
{
    var query = DbContext.Set<T>();

     foreach (var includeProperty in includeProperties)
     {
         query = query.Include(includeProperty);
     }

    return query.Find(id);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM