我正在使用.Net 4.5和Entity Framework 6来创建REST Web API。 在我的Update方法中,我需要将在web api中收到的对象附加到dbcontext。我使用下面的代码实现了这一点。我现在要做的是使这段代码可以重用,这样我就可以为模型中的任何对象调用AttachToContext。
我知道我必须使用泛型类型T和TEntity,但我找不到任何合适的例子。
//Repository.cs
public void UpdateOrderItem(OrderItem orderItem)
{
try
{
AttachToContext(orderItem);
_context.SaveChanges();
}
catch (Exception e)
{
}
}
private void AttachToContext(OrderItem orderItem)
{
var entry = _context.Entry<OrderItem>(orderItem);
if (entry.State == EntityState.Detached)
{
var attachedEntity = FindExistingEntity(orderItem.Id);
if (EntityExists(attachedEntity))
{
UpdateEntityValues(attachedEntity, orderItem);
}
else
{
entry.State = EntityState.Modified;
}
}
}
private OrderItem FindExistingEntity(int id)
{
var set = _context.Set<OrderItem>();
return set.Find(id);
}
private void UpdateEntityValues(OrderItem existing, OrderItem updated)
{
var attachedEntry = _context.Entry(existing);
attachedEntry.CurrentValues.SetValues(updated);
}
private bool EntityExists(object entity)
{
return entity != null;
}
答案 0 :(得分:1)
您的AttachToContext
依赖于主键属性orderItem.Id
,将其更改为动态,您可以为所有实体引入接口和实现,或者只将id作为参数传递。
<强>接口强>
public interface IEntity
{
public int Id { get; set; }
}
public class OrderItem : IEntity
{
// body
}
然后修改AttachToContext
,如下所示。
private void AttachToContext<T>(T entity) where T : class, IEntity
{
var entry = _context.Entry(entity);
if (entry.State == EntityState.Detached)
{
var attachedEntity = FindExistingEntity<T>(entity.Id);
if (EntityExists(attachedEntity))
{
UpdateEntityValues(attachedEntity, entity);
}
else
{
entry.State = EntityState.Modified;
}
}
}
private T FindExistingEntity<T>(int id) where T : class
{
var set = _context.Set<T>();
return set.Find(id);
}
private void UpdateEntityValues<T>(T existing, T updated) where T : class
{
var attachedEntry = _context.Entry(existing);
attachedEntry.CurrentValues.SetValues(updated);
}
用法为AttachToContext(orderItem);
。
传递密钥
private void AttachToContext<T>(T entity, params object[] id) where T : class
{
var entry = _context.Entry(entity);
if (entry.State == EntityState.Detached)
{
var attachedEntity = FindExistingEntity<T>(id);
if (EntityExists(attachedEntity))
{
UpdateEntityValues(attachedEntity, entity);
}
else
{
entry.State = EntityState.Modified;
}
}
}
private T FindExistingEntity<T>(object[] id) where T : class
{
var set = _context.Set<T>();
return set.Find(id);
}
private void UpdateEntityValues<T>(T existing, T updated) where T : class
{
var attachedEntry = _context.Entry(existing);
attachedEntry.CurrentValues.SetValues(updated);
}
用法为AttachToContext(orderItem, orderItem.Id);
。
另一种方法是使用对象集来获取主键属性,然后使用反射来获取值。 this post已解释了获取主键属性的问题。