如何使用实体框架保存对导航属性的更改

本文关键字:属性 导航 何使用 实体 框架 保存 | 更新日期: 2023-09-27 18:12:26

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

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

属性是一个表,项为表,PropertyItem是多对多关系中涉及的表。

EF没有为PropertyItem生成实体,所以我试图通过属性实体添加项目。更改属性项的导航属性不会保存更改。

我已经尝试过延迟加载,但它没有区别

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();
        }
    }

任何帮助都是感激的,谢谢,

如何使用实体框架保存对导航属性的更改

要做您想做的事情,您需要有一个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跟踪更改,则不会检测到关系更改,因此更改不会应用到DB。

所以你需要在你的一个仓库中实现这个方法。

还有其他选项,直接执行SQL INSERT命令与相应的键,即执行INSERT INTO PropertyItem( <col names>) VALUES (<col values parameters>)。为此,您需要使用DbContext.Database.ExecuteSqlCommand来接受查询和相应的参数。如果您这样做,DbContext将不会立即知道关系的变化,但是,由于您使用的是短期DbContext,这对您来说不是问题。