我正在尝试弄清楚如何使用实体框架中的导航属性更新相关对象。 我有一个这样的订单类:
public class BaseOrder
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int OrderId { get; set; }
[Required]
public bool Flag { get; set; }
public int Price { get; set; }
public string ProjectName { get; set; }
public PaymentMethod? PaymentMethod { get; set; }
public Status Status { get; set; }
public decimal Discount { get; set; }
public String Comments { get; set; }
public String InnerComments { get; set; }
public virtual Customer Customer { get; set; }
public virtual Product Product { get; set; }
public virtual Contact FinanceContact { get; set; }
public virtual Contact Contact { get; set; }
}
我还使用通用代表
实现了存储库和工作单元模式 public abstract class BaseRepository<T> : IRespository<T>, IDisposable
where T:class
{
/*--------------------Members---------------------*/
protected readonly DbContext _context;
protected readonly DbSet<T> _dbSet;
private string _primaryKey;
private bool _disposed;
/*--------------------Methods---------------------*/
public BaseRepository(DbContext context)
{
_context = context;
_disposed = false;
_dbSet = context.Set<T>();
//Set the primary key of the T type
var objectContext = ((IObjectContextAdapter)_context).ObjectContext;
var objectSet = objectContext.CreateObjectSet<T>();
var entitySet = objectSet.EntitySet;
_primaryKey = entitySet.ElementType.KeyMembers[0].ToString();//We assume there is one key , else fml
}
public void Add(T entity)
{
_dbSet.Add(entity);
}
public void Update(T entity)
{
var objKey = GetObjectKey(entity);
var originalObj = _dbSet.Find(objKey);
var entry = _context.Entry<T>(originalObj);
entry.CurrentValues.SetValues(entity);
NavigationPropertiesCopy(originalObj, entity);
_context.SaveChanges();
}
public void Remove(object key)
{
T entity = _dbSet.Find(key);
if (entity == null)
throw new WrongIdException();
_dbSet.Remove(entity);
}
public T Get(object key)
{
return _dbSet.Find(key);
}
public IQueryable<T> GetAll()
{
return _dbSet;
}
public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
{
return _dbSet.Where(predicate);
}
public void Dispose()
{
if (!_disposed)
{
_context.Dispose();
_disposed = true;
}
GC.SuppressFinalize(this);
}
protected virtual void NavigationPropertiesCopy(T target,T source)
{
//The update function is using CurrentValues.SetValues method to copy the scalar properties
//This method doesn't support navigation properties copy
//If object is using navigation properties , he need to override this method and handle the copy
}
private object GetObjectKey(T entity)
{
return typeof(T).GetProperty(_primaryKey).GetValue(entity, null);
}
}
当我尝试编写通用更新方法时,我注意到entry.CurrentValues.SetValues(实体)只更改了标量值,所以我决定每个 具体的存储库将处理其导航属性的更新。 但是我注意到当我将订单的产品更新为另一个现有产品时, 实体不会更改关系,而是将新产品添加到数据库中。 我尝试在Order类中添加ProductId属性,但由于某种原因,它们没有同步,实体仍然添加了新产品。
我的问题是: 1.我可以在通用基类中编写更新吗?如果是这样,怎么样? 2.如果没有,更改相关对象的正确方法是什么。
亲切的问候, Tal Humy