2

次のエンティティ フレームワーク モデルがあります。

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

class Animal{
    string Name;
    DateTime DOB;
}

問題:

開始日が >= 2013/01/01である農場のコレクションとその動物を選択したいと考えていますが、DOB >= 2013/06/01 でフィルター処理されています。

私は次のことを試しました:

試行 1 :

//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");

試行 2 :

//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.

トライ3

これを読んだ後: 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... 

上記の仕組みを説明したい人はいますか?

基本的に、クエリは親エンティティと必要なパラメーターによってフィルター処理された子エンティティを選択します。エンティティ フレームワークは、「リレーションシップ フィックスアップ」を介して、選択された子が選択された親に関連付けられていることを認識しているため、親コレクションにも追加されます。ハックな解決策のように見えますが、実際に機能します。

--アンドレイ・D.

4

4 に答える 4

2

上記の仕組みを説明したい人はいますか?

以下を 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、フィルター処理された を含むすべての が 2 つ含まれAnimalsます。

Distinct重複をフィルタリングします。

于 2013-09-25T18:31:13.093 に答える
0

これを試すことができます:

var filteredObjects = db.Farm.Where(x=>x.StartDate >= <startDateVariable> && x.Animal.Where(y=>y.DOB >= <DOBVariable>));
于 2013-09-26T09:41:48.970 に答える
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();
于 2013-09-25T18:39:41.507 に答える
0

通常、この時点でサーバーに戻り、EF から呼び出すことができる関数を作成します。これらのようなインスタンスの多くの時間を簡単にします。

(申し訳ありませんが、SQL をテストせずにこれを入力しています。Psudocode と考えてください)

Create Procedure GetFarmAnimals @StartDate as [Datetime], @DOB as [Date] As Select * Farm left join Animals on (実際の外部キーの組み合わせが何であれ), Farm.Startdate = @StartDate and Animal.DOB = @DOB end

次に、関数を EF にインポートします。

于 2013-09-25T18:52:00.620 に答える