使用部分加载的集合获取实体框架对象

时间:2013-09-25 18:06:29

标签: c# linq entity-framework

我有一个实体框架模型,其中包含以下内容:

class Farm{
    string owner;
    List<Animal> animals;
    DateTime StartDate;
}

class Animal{
    string Name;
    DateTime DOB;
}

问题:

我想选择一个农场集合,其开始日期为&gt; = 2013/01/01 及其动物,但已过滤< / strong> by DOB&gt; = 2013/06/01。

我尝试了以下内容:

Try1

//This still shows all animals from each farm, if there is at least one
//animal with the required DOB

var x = context.Farm.Where(y => y.StartDate >= myDate 
                           && y.Animal.Any(z => z.DOB >= otherDate)
                          ).Include("Animal");

Try2

//I subclassed the Farm class because i cant instantiate the class 
//from Entity Framework directly, and that should be my return type.
class Temp:Farm{}

var x = context.Farm.Where(y => y.StartDate >= myDate).Include("Animal")
        .Select(z => new Temp(){ 
                    owner = z.owner, 
                    animals = new TrackableCollection<Animal>(){ z.animals.Where(y => y.DOB >= newDate).SingleOrDefault() });

//Couple of things here:
//1: I instantiated a new TrackableCollection because thats what the collection
//type of Animal is inside Entity Framework.
//2: This still doesnt work for some reason, if i use this approach, the list 
//of animals in the farm comes with 0 elements.

Try3

阅读本文后:Ef-query-with-conditional-include

var x = (from farm in ctx.Farm
        from animal in farm.Animal
        where animal.DOB => newDate
        select new{farm, animal}).AsEnumerable().Select(x=> x.farm).Distinct().ToList();
//I have no idea how this works, but it does... 

任何人都在关心如何解释上述情况?

基本上,查询是选择父实体和由所需参数过滤的子实体,实体框架通过“关系修复”知道所选子项与所选父项相关联,因此它们被添加到父集合中好。我认为这是一种hacky解决方案,但确实有效。

- Andrei D。

4 个答案:

答案 0 :(得分:2)

  

任何人都在关心如何解释上述情况?

将以下内容视为两个单独的查询:

var x = (from farm in ctx.Farm
        from animal in farm.Animal
        where animal.DOB => newDate
        select new{farm, animal}).AsEnumerable().Select(x=> x.farm).Distinct().ToList();

爆发:

//Give me all farms
from farm in ctx.Farm

//Give me farms with animals with a DOB greater or equal to newDate
from animal in farm.Animal
where animal.DOB => newDate

//Select both so that neither are discluded from the query during execution
select new{farm, animal})

在执行时,查询将只包含上面的数据,因此结果将包含每Farm个中的两个,包括已过滤的Animals

Distinct过滤重复项。

答案 1 :(得分:0)

您可以尝试:

var result = context.Farms.Where(y => y.StartDate >= myDate)
                          .Select(z => new Farm { 
                            owner = z.owner, 
                            StartDate = z.StartDate,
                            animals = z.animals.Where(x => x.DOB >= newDate).ToList() 
                }).ToList();

答案 2 :(得分:0)

此时我经常翻到服务器并创建一个我可以从EF调用的函数。只是让像这样的实例更容易。

(对不起,我正在键入此内容而不测试sql。将其用于Psudocode)

创建过程GetFarmAnimals   @StartDate为[Datetime],   @DOB为[日期] 如  选择*农场左加入动物  on(无论你的实际外键组合是什么)  其中Farm.Startdate = @StartDate和Animal.DOB = @DOB 端

然后将该功能导入EF。

答案 3 :(得分:0)

你可以试试这个:

var filteredObjects = db.Farm.Where(x=>x.StartDate >= <startDateVariable> && x.Animal.Where(y=>y.DOB >= <DOBVariable>));