使用实体框架更新存储库模式中的方法

时间:2014-05-12 14:33:34

标签: entity-framework repository-pattern unit-of-work

我正在尝试弄清楚如何使用实体框架中的导航属性更新相关对象。 我有一个这样的订单类:

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

0 个答案:

没有答案