我正在尝试使用实体框架在多对多表中添加复合键,但它没有添加键。
这是我们的服务方法,它将一个项目添加到一个属性
属性是一张桌子, 项目是表格, PropertyItem是涉及多对多关系的表。
EF不会为PropertyItem生成实体,因此我尝试通过属性实体添加项目。更改属性中项目的导航属性不会保存更改。
我尝试过Lazy Loading但它没有什么区别
public void addPropertyItem(int propertyId, int itemId)
{
ErrorHandler errorHandler = new ErrorHandler();
try
{
Item item = itemRepo.getSingle(i => i.itemId.Equals(itemId));
if (item == null)
{
errorHandler.addException("Item does not exist.");
}
Property property = propertyRepo.getSingle(p => p.propertyId.Equals(propertyId), p => p.Items);
if (property == null)
{
errorHandler.addException("Property does not exist.");
}
if (!errorHandler.hasErrors())
{
foreach (Item i in property.Items)
{
if (i.itemId == item.itemId)
{
return;
}
}
property.Items.Add(item);
propertyRepo.update(property);
}
使用以下代码检索数据:
public virtual T getSingle(Func<T, bool> where,
params Expression<Func<T, object>>[] navigationProperties)
{
T item = null;
using (var context = new PropertyManagementDBEntities())
{
IQueryable<T> dbQuery = context.Set<T>();
//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);
item = dbQuery
.FirstOrDefault(where); //Apply where clause
}
return item;
}
这是DAL方面的更新。
public virtual void update(params T[] items)
{
using (var context = new PropertyManagementDBEntities())
{
foreach (T item in items)
{
context.Entry(item).State = System.Data.EntityState.Modified;
}
context.SaveChanges();
}
}
感谢任何帮助,谢谢,
答案 0 :(得分:1)
要做你想做的事,你需要有一个DbContext来跟踪变化,即你需要实现这样的方法:
using (var context = new PropertyManagementDBEntities())
{
// Implement here code that
// 1. Get the Property (or properties)
// 2. Get the Item (or items)
// 3. Adds the Item (or items) to the Property (or proerties)
context.SaveChanges();
}
通过这种方式,DbContext跟踪更改(即知道发生了什么),以便它知道新关系(它确实“关系修复”),并且在调用SaveChanges
时保存新的关系。
如果没有DbContext跟踪更改,则不会检测到关系更改,因此更改不会应用于数据库。
所以你需要在你的一个回购中实现这个方法。
还有其他选项直接使用相应的键执行SQL INSERT
命令,即执行INSERT INTO PropertyItem( <col names>) VALUES (<col values parameters>)
。为此,您需要使用接受查询的DbContext.Database.ExecuteSqlCommand和相应的参数。如果你这样做,DbContext将不会立即知道关系的变化,但是,当你使用短暂的DbContexts时,这对你来说不是问题。