2

問題があり、誰かが助けてくれることを願っています。

これは私の実際の例です。4 つのテーブルがあります:
Person
Plan
Coverage と CoveredMembers

一人一人が多くのプランを持つことができ、それらのプランのそれぞれが多くの補償範囲を持つことができます。これらの各カバレッジには、多数の CoveredMembers を含めることができます。

Plan.PlanType == 1 および CoveredMembers.TermDate == null にフィルターを適用するクエリが必要です。このクエリは、終了していない医療タイプのプランを持っている人を呼び戻す必要があります。しかし、すべての子レコードも含まれている必要があります。プラン、適用範囲、および対象となるメンバーでフィルターに適合する各人。

この SQL ステートメントはまさにそれを行います。

SELECT Person.*, Plans.*, Coverages.*, CoveredMembers.* 
FROM Person P 
INNER JOIN Plan PL ON P.PersonID = PL.PersonID 
INNER JOIN Coverage C on PL.PlanID = C.PlanID 
INNER JOIN CoveredMember CM on C.CoverageID = CM.CoverageID 
WHERE CM.TermDate = NULL AND PL.PlanType = 1 

EF(4.0対2010)でこれを行いました

var Q from p in context.Persons
join pp in context.Plans
on p.PersonID  equals pp.PersonD
join c in context.Coverages
on pp.PlanID equals c.PlanID 
join cm in context.CoveredMember
on c.CoverageID equals cm.CoverageID
where cm.TermDate == null && pp.PlanType = 1 && 
pp.ActiveFlag == true 
select p;

それから

var people = Q.Include(people => 
people.Plans.Select(plans => plans.Coverages.Select(cc =>  cc.CoveragedMembers)))
.ToList ();

var people = Q 行にブレークポイントを設定して、

((System.Data.Objects.ObjectQuery)Q).ToTraceString();

ToList() を使用してクエリが実際にデータベースに送信される前 (include ステートメントの前)、そのクエリを取得し、返すべきレコードの正確な量を取得します。

次に、(SQL プロファイラーで) SQL トレースを実行し、クエリをデータベースに送信します (include ステートメント)。データベースに送信されている sql ステートメントがすべてのフィルタリングを失っていることがわかります。基本的に同じ人を返しますが、子オブジェクトのフィルターはなくなり、これらの人々のすべてのデータを返しています。(plan.PlanType = 1 および coveredMember.TermDate = null がありません)

多分これはこれを達成する方法ではありませんか?誰か考えがありますか?EFでも可能ですか?これは非常に単純な SQL ステートメントです (4 つのテーブルにまたがっていますが) ので、これがそれほど大きな問題になるとは思いませんが、何かを正しく行わないことが問題であると確信しています。

4

2 に答える 2

0

あなたcannot use filtering with Eager loading (Include)

したがって、以下のようなことができます(これはサンプルコードです)

public Company Get(int id)
{
    var query = from c in
                    (from co in db.Companies
                        where co.Id == id
                        select new
                        {
                            Company = co,
                            CompanyPerson = from person in co.Persons
                                            where person.IsActive && !person.IsDeleted
                                            select person
                        })
                select c;

    //Create my company object
    Company company = new Company();
    foreach (var item in query)
    {
        company = item.Company;

        //Add persons to my company object
        foreach (var companyPerson in item.CompanyPerson)
        {
            company.Persons.Add(companyPerson);
        }
    }
    return company;
}

詳細については、この投稿を確認してくださいEager Loading(include)with filter in Entity Framework

これがお役に立てば幸いです。

于 2013-01-26T16:44:02.807 に答える