Entity Framework 5に子オブジェクトの子オブジェクトを含める方法


138

とを使用Entity Framework 5 code firstしていASP.NET MVC 3ます。

子オブジェクトの子オブジェクトを作成するのに苦労しています。以下は私のクラスです。

アプリケーションクラス。

public class Application
{
     // Partial list of properties

     public virtual ICollection<Child> Children { get; set; }
}

子クラス:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

ChildRelationshipTypeクラス:

public class ChildRelationshipType
{
     public int Id { get; set; }

     public string Name { get; set; }
}

すべてのアプリケーションを返すためのリポジトリのGetAllメソッドの一部:

return DatabaseContext.Applications
     .Include("Children");

Childクラスには、ChildRelationshipTypeクラスへの参照が含まれています。アプリケーションの子を操作するには、次のようにします。

foreach (Child child in application.Children)
{
     string childName = child.ChildRelationshipType.Name;
}

ここで、オブジェクトコンテキストが既に閉じているというエラーが発生します。

ChildRelationshipType上記のように、各子オブジェクトにオブジェクトを含める必要があると指定するにはどうすればよいですか?


回答:


256

ライブラリを含める場合は、文字列の代わりにラムダ式を取るメソッドのSystem.Data.Entityオーバーロードを使用できInclude()ます。次にSelect()stringパスではなくLinq式で子をオーバーできます。

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));

6
GraemeMillerが言ったように、強く型付けされたクラスは、文字列を使用するよりも保守性に優れています
Ryan

lambaメソッドはどのバージョンが利用可能になりましたか?私はEF 4.0コードベースで立ち往生しています。ラムダを機能させることができません。ご意見をお寄せいただきありがとうございます。
granadaCoder 14

5
これはEF 4で機能します。参照を必ず追加してくださいSystem.Data.Entity;
Ryan Amies

5
FYI-EF 6では、名前空間はMicrosoft.Data.Entity
Brad

EF 5を使用すると、.Select(x => x.Child)を取得できませんでしたが、これは機能しました-Entities.UserProfile storedProfile = db.UserProfiles .Include(s => s.ShippingAddress).Include(st => st.ShippingAddress。 StateProvince).Include(b => b.BillingAddress).Include(bs => bs.BillingAddress.StateProvince).FirstOrDefault(x => x.UserId == userId);
Geovani Martinez 2018

91

.NET CoreのEF Coreでは、次のキーワードを使用できますThenInclude

return DatabaseContext.Applications
 .Include(a => a.Children).ThenInclude(c => c.ChildRelationshipType);

子供コレクションの子供を含める:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);

6
ありがとう!!! 本当に役に立ちました!時々あなたは間違ったインテリセンスを得るかもしれません、それを無視して構築してください!:)
muhihsan 2017

いいね、私は.netコアを探していました:)
Andy Clarke

1
そして、Childrenがコレクションであり、その下にプロパティを含める必要がある場合はどうなりますか?
ドドブリアン

そのための過負荷を見つけました。最初は明らかではなかった。
ドドブリアン

1
@dodbrianオーバーロードは何でしたか?.ThenIncludeをネストしようとしています。子はコレクションです。
グレッグハーディン

22

私は最終的に次のことをすることになり、それはうまくいきました:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");

76
強く型付けされた方が良いです。マジックストリングはリファクタリングに適していません
GraemeMiller 2012年

2

Generic Repositoryパターンを使用し、これに対する汎用ソリューションを実装する良い例は、次のようになります。

public IList<TEntity> Get<TParamater>(IList<Expression<Func<TEntity, TParamater>>> includeProperties)

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}

上記のメソッドをどのように呼び出しますか?あなたは、例えば、提供することができます
Jamee

@Jamee -List <Expression <Func <PersonObject、object >>> includers = new List <Expression <Func <PersonObject、object >>>(); includers.Add(x => x.FirstName); Get <PersonObject>(includers);
gcoleman0828 16

1
そしてクエリは...から来ますか?
Doug Beard

@DougBeardさん、申し訳ありませんが、質問には従いません。
gcoleman0828 2017

1
@ gcoleman0828上記のコードスニペットのクエリ変数。魔法のようにインスタンス化されていますか?それはどこから来たのですか?
Doug Beard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.