4

サーバーが Entity Framework を ORM として使用するクライアント/サーバー アプリケーションがあります。クライアントに送信されるすべてのエンティティは、DTO クラスによって表されます。

Entity Framework と DTO クラス間のマッピングは、AutoMapper を使用して処理されます。

次のテーブルがあるとします。

Person (string Name, int CountryID) Country (int CountryID, int Population, string Name)

これらは、次の EF クラスによって表されます。

class Person
{
 public string Name { get; set; }
 public int CountryID { get; set; }
 public Country Country { get; set;}
}

class Country
{
 public int CountryID { get; set; }
 public int Population { get; set; }
 public string Name { get; set;}
}

これは、次の DTO で表されます。

class PersonDTO
{
 public string Name { get; set; }
 public CountryDTO Country { get; set;}
}

class CountryDTO
{
 public int CountryID { get; set; }
 public int Population { get; set; }
 public string Name { get; set;}
}

データベースの初期状態は、空の Person テーブルと、1 つのエントリ (1, 123, 'CountryXYZ') を持つ Country テーブルを表します。

クライアントのアプリ タスクは、新しい Person Entity を作成し、その Country-Reference を使用可能な「CountryXYZ」Country-Entity にアタッチすることです。

そのために、クライアント アプリはまず利用可能な CountryDTO を要求します。次に、新しい PersonDTO インスタンスを作成し、Country プロパティを、サーバーから受信した唯一の CountryDTO に設定します。次に、この PersonDTO インスタンスがサーバーに送り返されます。次に、サーバーは PersonDTO-instance を Person-instance にマップします。

サーバーの最後の手順は、Person-instance を ObjectContext に格納し、ObjectContext.SaveChanges() を呼び出すことです。

このアプローチの問題点は、ObjectContext.SaveChanges() を呼び出すとすぐに、使用可能な Country 行を使用する代わりに、データベースに新しい Country 行が作成されることです。ここで何が欠けていますか?

私はEFを初めて使用しますが、このユースケースはかなり一般的だと思います...簡単に修正できることを願っています。

問題の説明が十分に明確でない場合は、お知らせください。

ありがとう!

4

2 に答える 2

2

クライアントがサーバーから既に受信した国 (既存のもの) を常に使用することがわかっている場合は、保存ロジックを変更して使用することができます。

objectContext.PersonSet.AddObject(personToSave);
objectContext.ObjectStateManager
             .ChangeObjectState(personToSave.Country, EntityState.Unchanged);
objectContext.SaveChanges();

メソッドを使用AddObjectすると、エンティティとそのすべての関係が追加済みとしてマークされ、状態を再構成しない限り、新しいオブジェクトとしてデータベースに挿入されます。

エンティティは FK プロパティも公開するため、国のインスタンスを作成する代わりに、DTO をエンティティにマップし直すときに FK プロパティを使用できます。このような場合、リレーションは整数列のみで表現されるため、リレーションの状態を変更する必要はありません。

クライアントが両方PersonCountry1 回の呼び出しで作成できる場合、既存のエンティティと新しいエンティティを区別するために DTO に何らかのフラグが必要になるか、データベースにクエリを実行してそのようなエンティティがCountry既に存在するかどうかを確認する必要があります。

于 2012-04-07T16:54:45.787 に答える
1

これは、セルフ トラッキング エンティティの使用が役立つ可能性が高い例です。

T4 テンプレートを使用してエンティティ クラスを生成し、WCF を使用してネットワーク上でラウンドトリップできます。ただし、エンティティを含むアセンブリをクライアントとサーバーで共有する必要があります。

あなたが両方を管理しており、両方に .Net を使用している場合、私はそのルートに行きます。

于 2012-04-06T23:59:24.443 に答える