1

タイトルについて申し訳ありませんが、適切な説明がわかりませんでした。

私は4つの層を持っています:

  • Core Layer : DTO、サービスおよびリポジトリ用のインターフェースが含まれています。
  • ビジネス層 : ビジネス ロジックを処理する「サービス」が含まれます。
  • Data Access Layer : データベース アクセスとエンティティの 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 だけを返すこともできません。

非常に便利なので、汎用リポジトリを削除したくありませんが、データベースを変更せずに安全に実行する別の方法がわかりません (これはできません)。

それで、私は何をしますか?

4

2 に答える 2

0

Here's a couple of ideas that I'd try. Not sure if any of them suits your needs, but might get you started (or start a discussion at least :) ):

1; Introduce an interface for your DTOs, like IDto. Then you can change the generic repository to return Task<IDto> instead of Task. Convert the entity to the concrete Dto inside the Add method, return through the IDto reference, then convert it back in the service.

2; If you have a generic repository like IRepository<TEntity>, or Repository<TEntity>, then you might try introducing another parameter to the generic repository and make it an IRepository<TEntity,TDto>. This way you can keep the generic nature of your architecture, but also return Task<Dto> from the Add method.

3; You can go even further: create an IDto<TEntity> interface. And then you can have a User entity and a UserDto:IDto<User>. Then you can change the return type of the Add method to Task<IDto<TEntity>>. Or, again, use the two-parametered repository IRepository<TEntity,TDto>, and add constraints, so that TDto must implement IDto<TEntity>.

于 2017-08-30T12:46:57.030 に答える