2013-06-19 9 views
5

数週間前に新しいプロジェクトを開始し、EF Code Firstを試してみることにしました。 NHIbernateを以前使用していましたが、ORMのアウトオブザ - MSからの弓、そしてこれまでのところ、私が複雑なオブジェクトを作るまでは素晴らしかったです。 - EFコードファーストとDALを処理するための AzureのWCFの役割を次のようにEF vs Nhibernate Merge Disconnected Object Graph

マイプロジェクト階層があります。 Azure WebSite MVC 4とノックアウトの役割 - クライアントに対処する。ここで (私たちは、異なるプラットフォームからサービスにアクセスする必要があります将来のためWCFRoleを作成した)

は私がとのトラブルを抱えている、非常に基本的なEFコードファーストデザインです: -I'mのみ転送しますサービスとサイトの間のDTOを定義し、存在する場合は内部DTOをマッピングするジェネリックマッパーを作成しました。 - 私はCityテーブルとCityプロパティを持つAddressオブジェクトを持っています(名前だけでなく特別な機能のためにCityをプロパティとして必要とします)

クライアントは都市のリストを知っていて、既存の都市 私は新しいアドレスを追加しようとすると、新しい都市が1を既存の古いデータを使用して作成されて、私はすでにEFは、私が読んだものから切り離されたオブジェクトとをマージする方法を知らないので、これが起こることを得ましたどのようなマージをもサポートしておらず、シンプルではない快適な解決策はObject Stateを管理することだけです - Cityオブジェクトの状態をUnchangedに変更してください。

しかし、大きな複雑なDB設計でこれを処理することは恐ろしい聞こえる

私の質問 - これを処理するのがベストプラクティス/簡単な方法は何ですか? は、私のような解決策を考えました - しかし、すべてのオブジェクトを行くSaveChangesメソッドをオーバーライドし、IDは変更なしに追加さからそれを変更するにはnull/0 /他のいくつかの規則がない場合は - このソリューションを行うことができますか?

私の2番目の質問 - 私はNHibernate(接続されたオブジェクトを持つ)に多くの経験を持っているので - 私はNHibernateがこれをどう受け止めているのだろうか?私は、NHibernateが切断された複雑なオブジェクトに再接続するAutoMagic Merge機能を持っているところを読んでいます。これは本当ですか?私の基本的な切断されたAddress-> Cityデザインは、そのAutoMagic Mergeですぐに使えるでしょうか? それを使用するとどのような影響がありますか?

ありがとうございました:)

アップデート:問題の簡略化されたコードです。

「FromDto」
public void Add(AddressDto address) 
    { 
     using (var context = new MyContext()) 
     { 
      context.Addresses.Add(address.FromDto<Address>()); 

      context.SaveChanges(); 
     } 
    } 

はそれがシティ(およびCity.IDプロパティ)

を含むすべての情報を使用して新しいアドレスを作成し、一般的なマッパーの拡張である:

public class Address 
{ 
    public int ID { get; set; } 

    public virtual City City { get; set; } 
} 

public class City 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 
    public virtual Zone Zone { get; set; } 
} 

public class MyContext : DbContext 
{ 
    public MyContext() : base("TransportService") { } 

    public virtual DbSet<City> Cities { get; set; } 
    public virtual DbSet<Address> Addresses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Address>() 
      .HasRequired(x => x.City) 
      .WithMany().WillCascadeOnDelete(true); 

    } 
} 

新しいアドレスを追加します

これは新しい都市を作成する代わりに、旧市街への参照を使用してになります。

+1

あなたの質問を示すコードを表示すると、これに答えるほうがはるかに簡単です。 EFは切断されたオブジェクトをマージすることができますが、_relationship fixup_というバックグラウンドプロセスがありますが、コードなしではこれが役立つかどうかは分かりません。 –

+0

私は基本的なデザインを与え、私はコードを追加します。 –

+1

私はリレーションシップフィックスアップについて何を読んだのですか?それは手動での再接続です。現在のコンテキストにすべてのオブジェクトを再接続する必要がある場合にのみ機能します。 NhibernateはプリミティブKeyで自動マージしています。この機能は、EFがそれらのプロジェクトでも候補者ではない大きな複雑なオブジェクトに非常に面倒を節約します.3〜4レベルの内部オブジェクトが必要です。離れた環境であなたに身に着ける... –

答えて

3

私はEFは、自動マージを持っていないことを、彼らのマージ機能は、これまでのところ唯一の手動マージされ、そしてそれはContextオブジェクトがメモリ内のオブジェクトのすべての依存関係を持っている場合にのみ動作しますました。

マルチレベルの切断されたオブジェクトを扱い、手動で再接続することは多くの作業であり、本当に変わったバグを扱うことができます(新しい都市がどこに作成されたのか、 IDがあっても新しいものを作成しました)

Nhibernateはこの戦いに勝利しました Nhibernateには自動マージ機能があり、切断されたオブジェクトにはマージしようとするIDがありますそれは成功しています(私の経験から) EFに比べて物事を稼働させるのにもう少し設定していますが、それは問題の価値があります。

+2

私は同意します。 Entity Frameworkの大きな欠点。はい、NHibernateで正しいことを得るためにいくつかの "微調整"が必要ですが、うわー、あなたは.Merge()とB00Mを通して実行します!あなたは終わった。あなたの質問をフォローアップしてくれてありがとう...今私は狂っていない知っている。 – granadaCoder

+0

「手動トラッキング」がどのように行われているかを示す良いリンクです。このリンクは「切断されました」です:::: http://www.entityframeworktutorial.net/EntityFramework4.3/deleteentity-using -dbcontext.aspx – granadaCoder

+0

E7は、万一、切断されたエンティティをより良くサポートしますか? – HappyNomad

関連する問題