2017-08-30 12 views
1

申し訳ありませんが、私は適切な記述を見つけることができませんでした。挿入後にC層のエンティティの変更がDTOに反映されない

  • コア層:サービスとリポジトリのDTOの、インタフェースが含まれてい

    私は4層を持っています。

  • ビジネス層:ビジネスロジックを処理する「サービス」が含まれます。
  • データアクセスレイヤー:データベースへのアクセスとエンティティのDTOへの変換を処理するリポジトリが含まれています。
  • プレゼンテーション層:UIのものが

私は最善の解決方法がわからない問題に遭遇しました。

// The AdministrationRate has an ID property, Entity Framework does treat the property as an Identity and does increment it. 
var adminRate = new AdministrationRate() {FosterChildID = fosterChild.ID}; 
await adminRateService.AddAdministrationRate(adminRate); 

AdministrationRateService:

public async Task AddAdministrationRate(AdministrationRate administrationRate) => await repo.AddAdministrationRate(administrationRate); 

AdministrationRateRepository:

//I use a generic repository to avoid code repition. 
//Notice the DTO to entity conversion. ID is not set in the conversion. 
public async Task AddAdministrationRate(AdministrationRate administrationRate) => await Add(administrationRate.ToEntity()); 

リポジトリ:私は非同期的にそうように、データベースにエンティティを追加してい

public async Task Add(TEntity entity) 
{ 
    using (var db = new DatabaseContext()) 
    { 
     db.Entry(entity).State = EntityState.Added; 
     await db.SaveChangesAsync(); 
    } 
} 

そして、それが問題になるのは、エンティティの新しく生成されたIDがDTO(DTO.ID = 0)に反映されていないということです。

エンティティをプレゼンテーションレイヤー内のDTOに変換して非同期にする必要があるため、更新されたエンティティを返すことはできません。

汎用リポジトリのためIDだけを返すこともできません。

非常に便利なので汎用リポジトリを取り除きたいとは思っていませんが、データベースを変更せずに安全に行うことはできません。

どうすればいいですか?

答えて

0

回答: 私はこの問題の2つの解決策を見つけました。後者は、私が実際に行っている解決策です。


解決方法1:

私は、その後のいずれかでそれをオーバーライド、仮想ジェネリックリポジトリのAddメソッドをマークすることにより、Addメソッドは、エンティティのIDを返す作ることができることを考え出しました特定のリポジトリを呼び出し、最後に呼び出しコードから結果をキャッチします。これはもちろん、より多くのコードを意味しますが、エンティティからDTOの間違ったレイヤーに変換することはありません(これはオプションではありません)。


解決方法2:

どうやらawaitキーワードではなく、resultのようにそれを阻止する、非同期タスクの結果の型を返しますので、私は私のリポジトリからDTOに変換して返すことができました。

AdministrationRateRepository:

public async Task<AdministrationRate> AddAdministrationRate(AdministrationRate administrationRate) => (await Add(administrationRate.ToEntity())).ToModel(); 

私がToEntity()ToModel()のメソッドを非同期にする必要があるかどうか、誰かがコメントできたらいいと思います。

編集:ああ、誰かが投稿したことに気付かなかった。私はあなたの提案を見ていきます。Akos、ありがとう。

0

ここに私が試してみたいアイデアがいくつかあります。どちらかがあなたのニーズに合っているかどうかは確かではありませんが、始めに話を始めるかもしれません(または少なくとも議論を始めるかもしれません):

1; IDtoのようなあなたのDTOのためのインターフェイスを導入してください。その後、汎用リポジトリをTaskの代わりにTask<IDto>を返すように変更することができます。エンティティをAddメソッド内のコンクリートDtoに変換し、IDto参照を返し、サービスに戻します。

2; IRepository<TEntity>またはRepository<TEntity>のような汎用リポジトリがある場合は、汎用リポジトリに別のパラメータを導入してIRepository<TEntity,TDto>にしてみてください。この方法で、アーキテクチャの一般的な性質を保つことができますが、AddメソッドのTask<Dto>も返します。

3;さらに進むことができます:IDto<TEntity>インターフェイスを作成してください。そしてUserエンティティとUserDto:IDto<User>エンティティを持つことができます。次に、Addメソッドの戻り値の型をTask<IDto<TEntity>>に変更することができます。または、2つのパラメータを持つリポジトリIRepository<TEntity,TDto>を使用し、制約を追加して、TDtoIDto<TEntity>を実装する必要があります。

関連する問題