C#EF通用类包括

时间:2016-05-17 22:51:37

标签: c# entity-framework

我制作了一个GenericClass来从数据库中检索数据,这很好用。 但.Include(propname)不起作用。我添加了我在下面尝试过的代码。

GenericClass

public T GetItemByQuery<T>(Func<T, bool> query, List<string> NavigationProperties = null) where T : EntityObject
    {
        try
        {
            using (Entities context = new Entities())
            {
                var ObjectSet = context.CreateObjectSet<T>();
                if (NavigationProperties != null)
                {
                    foreach (string prop in NavigationProperties)
                    {
                        ObjectSet.Include(prop).AsParallel().ToList();
                    }
                }
                return ObjectSet.Where(query).FirstOrDefault();
            }
        }
        catch (Exception exc)
        {
            throw exc;
        }
    }

代码

Category category = bController.GetItemByQuery(new Func<Category, bool>(x => x.Active), new List<string> { "Products" });

调试器

Shop = null作为属性 Shop = null

这是shopUrls&gt; _relationships&gt; _relationships&gt; [0] enter image description here 我使用EF6

有人可以告诉我为什么category.Products为空?

感谢。

2 个答案:

答案 0 :(得分:0)

请尝试使用我的示例中的方法,它按预期工作,并且我认为Expression比字符串列表更好。

public virtual T GetById<T>(int id,  params Expression<Func<T, object>>[] includeProperties) where T : BaseEntity<int>
    {
       var result = Context.Set<T>();

       IQueryable<T> query = null;
       foreach (var property in includeProperties)
       {
           query = query == null ? result.Include(property) : query.Include(property);
       }

      return query == null ? result.SingleOrDefault(t=>t.Id == id) :
                              query.SingleOrDefault(t => t.Id == id);

    }

示例://将使用include

生成查询
 var model = Repository.GetById<Pan>(id, p => p.PanEmvTags.Select(t => t.EmvTag));

答案 1 :(得分:0)

这里有两件事是错的:

  • Func<T, bool> query。这应该是Expression<Func<T, bool>> query。如果您将其作为Func传递,则查询(ObjectSet)会在执行前强制转换为IEnumerable。这意味着谓词(query)未转换为SQL。首先从数据库中检索整个集合,然后将谓词作为LINQ应用于对象。

  • ObjectSet.Include(prop).AsParallel().ToList();。这将为每个include属性执行查询。相反,您应该通过每个导航属性扩展 ObjectSet:ObjectSet = ObjectSet.Include(prop);ObjectSet必须投放到IQueryable才能使其发挥作用。

所以方法应如下所示:

public T GetItemByQuery<T>(Expression<Func<T, bool>> query, params string[] NavigationProperties) where T : EntityObject
{
    using (Entities context = new Entities())
    {
        var ObjectSet = context.CreateObjectSet<T>().AsQueryable();
        foreach (string prop in NavigationProperties)
        {
            ObjectSet = ObjectSet.Include(prop);
        }
        return ObjectSet.Where(query).FirstOrDefault();
    }
}