如何使用Entity Framework保存对导航属性的更改

时间:2014-07-09 22:45:25

标签: c# sql-server linq entity-framework entity-framework-5

我正在尝试使用实体框架在多对多表中添加复合键,但它没有添加键。

这是我们的服务方法,它将一个项目添加到一个属性

属性是一张桌子, 项目是表格, 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();
        }
    }

感谢任何帮助,谢谢,

1 个答案:

答案 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时,这对你来说不是问题。