他のリポジトリで使用されるGenericEFRepositoryを作成しようとしています。私は以下のようにSaveメソッドを持っています。
public virtual void Save(T entity) // where T : class, IEntity, new() And IEntity enforces long Id { get; set; }
{
var entry = _dbContext.Entry(entity);
if (entry.State != EntityState.Detached)
return; // context already knows about entity, don't do anything
if (entity.Id < 1)
{
_dbSet.Add(entity);
return;
}
var attachedEntity = _dbSet.Local.SingleOrDefault(e => e.Id == entity.Id);
if (attachedEntity != null)
_dbContext.Entry(attachedEntity).State = EntityState.Detached;
entry.State = EntityState.Modified;
}
あなたは以下のコードのコメントで問題を見つけることができます
using (var uow = ObjectFactory.GetInstance<IUnitOfWork>()) // uow is implemented like EFUnitOfWork which gives the DbContext instance to repositories in GetRepository
{
var userRepo = uow.GetRepository<IUserRepository>();
var user = userRepo.Get(1);
user.Name += " Updated";
userRepo.Save(user);
uow.Save(); // OK only the Name of User is Updated
}
using (var uow = ObjectFactory.GetInstance<IUnitOfWork>())
{
var userRepo = uow.GetRepository<IUserRepository>();
var user = new User
{
Id = 1,
Name = "Brand New Name"
};
userRepo.Save(user);
uow.Save();
// NOT OK
// All fields (Name, Surname, BirthDate etc.) in User are updated
// which causes unassigned fields to be cleared on db
}
私が考えることができる唯一の解決策は、のようなリポジトリを介してエンティティを作成することでuserRepo.CreateEntity(id: 1)
あり、リポジトリはDbContextに接続されているエンティティを返します。しかし、これはエラーが発生しやすいようです。それでも、開発者はnew
キーワードを使用してエンティティを作成できます。
この特定の問題についてのあなたの解決策の提案は何ですか?
注:GenericRepositoryとIEntityインターフェイスを使用することの短所と長所についてはすでに知っています。したがって、「GenericRepositoryを使用しない、IEntityを使用しない、すべてのエンティティに長いIDを設定しない、実行しようとしていることを実行しない」というコメントは役に立ちません。