我正在嘗試編寫一個將被其他Repositories使用的GenericEFRepository。我有一個Save方法如下。在Entity Framework中保存實體的通用方法
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,不要做你正在嘗試做的事情」的評論無濟於事。
第一種方法存在一個小問題,將值類型屬性設置爲其默認值不會作爲更改獲取。例如,如果您保留一個登錄嘗試失敗的計數器,並且您想將其重置爲0,則它將不起作用。 – Stijn
在附加之前,您可以將其設置爲非0(例如1),然後在附加後將其更改爲零。 –