Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架6.1.3:投影-直接加载子对象的子对象_C#_Entity Framework_Linq_Projection_Anonymous Types - Fatal编程技术网

C# 实体框架6.1.3:投影-直接加载子对象的子对象

C# 实体框架6.1.3:投影-直接加载子对象的子对象,c#,entity-framework,linq,projection,anonymous-types,C#,Entity Framework,Linq,Projection,Anonymous Types,我的目标是只访问数据库一次,并通过筛选的子集合获取订单 为了实现这一点,我使用了一个投影: using (var db = new context()) { var query = from o in db.Orders select new {

我的目标是只访问数据库一次,并通过筛选的子集合获取订单

为了实现这一点,我使用了一个投影:

using (var db = new context())
            {
                var query = from o in db.Orders
                           select
                               new
                               {
                                   Order = o,
                                   Events = o.Events.Where(
                                       e => e.SomeBool 
                                       && e.SomeBool2
                                   ),

                                   EventsGroups = o.Events.Where(
                                       e => e.SomeBool 
                                       && e.SomeBool2
                                   ).Select(e => e.Groups),

                               };
            }
var query = from o in db.Orders
            select new
            {
                Order = o,
                Events = (from e in o.Events
                          where e.SomeBool && e.SomeBool2
                          select new
                          {
                              Event = e,
                              Groups = e.Groups,
                          }),
            };
这里的问题是没有加载子集合“事件组”。为了解决这个问题,我将其作为查询中的另一个属性“EventsGroups”加载,然后将其与事件一起放在一起

我的问题:是否有办法将子“组”直接加载到“事件”中,这样我就不必将它们作为另一个属性了

沿着

Events = o.Events.Where(
e => e.SomeBool 
&& e.SomeBool2
).Include(e => e.Groups), //this cannot be done this way

为什么我使用投影而不是快速加载:

基础类:

public class Order
{
    public Order()
    {
        Events = new HashSet<Event>();
    }

    public int Id { get; set; }

    public virtual ICollection<Event> Events { get; set; }
}

public class Event
{
    public Event()
    {
        Groups = new HashSet<Group>();
    }

    public int Id { get; set; }

    public bool SomeBool { get; set; }

    public bool SomeBool2 { get; set; }

    public virtual ICollection<Group> Groups { get; set; }
}

public class Group
{
    public Group()
    {
        Events = new HashSet<Event>();
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Event> Events { get; set; }
}
公共类秩序
{
公共秩序()
{
Events=newhashset();
}
公共int Id{get;set;}
公共虚拟ICollection事件{get;set;}
}
公开课活动
{
公共活动()
{
Groups=newhashset();
}
公共int Id{get;set;}
公共bool SomeBool{get;set;}
公共bool SomeBool2{get;set;}
公共虚拟ICollection组{get;set;}
}
公共课组
{
公共组()
{
Events=newhashset();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection事件{get;set;}
}

由于
包含
不能与匿名投影相结合,您需要以投影
顺序事件的相同方式投影
事件组
,即使用另一种匿名类型投影:

using (var db = new context())
            {
                var query = from o in db.Orders
                           select
                               new
                               {
                                   Order = o,
                                   Events = o.Events.Where(
                                       e => e.SomeBool 
                                       && e.SomeBool2
                                   ),

                                   EventsGroups = o.Events.Where(
                                       e => e.SomeBool 
                                       && e.SomeBool2
                                   ).Select(e => e.Groups),

                               };
            }
var query = from o in db.Orders
            select new
            {
                Order = o,
                Events = (from e in o.Events
                          where e.SomeBool && e.SomeBool2
                          select new
                          {
                              Event = e,
                              Groups = e.Groups,
                          }),
            };

您可以通过设置
Configuration.LazyLoadingEnabled=true来加载所有内容,不需要任何包含,当然。。。必须牢记业绩。。视情况而定

    public MyDatabaseContext(string databaseName)
        : base(databaseName)
    {
        Configuration.LazyLoadingEnabled = true;
    }

我相信这应该对你有用:

using (var db = new context())
{
  var query = db.Orders
    .Include(o=>o.Events)
    .Include(o=>o.Events.Select(e=>e.Groups))
    .Select(o=>new
    {
      Order = o,
      Events = o.Events.Where(e => e.SomeBool && e.SomeBool2)
    });
}
如果没有,这将:

using (var db = new context())
{
  var query = db.Orders
    .Include(o=>o.Events)
    .Include(o=>o.Events.Select(e=>e.Groups))
    .Select(o=>new Order
    {
      Id=o.Id,
      Events = o.Events.Where(e => e.SomeBool && e.SomeBool2).ToList()
    });
}

你能试试
o.Events.include(e=>e.Groups)吗(…
?你的意思是在投影内部吗?我不认为存在包含。对不起,你是对的。我认为@Ivans下面的答案应该有效。这打破了我只访问一次数据库的目标。这比我的方式更美好,更容易组合。我怀疑这是我可以避免循环的一个接近点从任意对象构造DTO对象。如果您确实有DTO对象,则可以直接投影到它们,而不是匿名类型-EF支持这一点。这在测试时不起作用。未加载组。获取命令和筛选的事件起作用,但事件上的组只有一个空列表。包含不起作用似乎在做任何事情,不管有没有它们,结果都是一样的。嗯。很有趣。一个简单的修复方法是在Include和Select之间添加
.ToList()
。这肯定会起作用,但是,您将检索所有事件记录,而不仅仅是那些符合
.Where
条件的记录。