插入一对多记录

最大限度

我遇到有关实体框架插入的问题。

我的应用程序具有以下两个实体:

  • 备忘录
  • 员工

备忘录可以与多个雇员链接。
一个雇员可以与多个备忘录链接。

这意味着多对多关系。我读了几篇文章,向我解释说应该创建一个联结表,这很明显。

这些文章使我了解到,让Entity Framework自动为我创建一个联结表。因此,我通过以下方式执行此操作:

备忘录

public Guid MemoId { get; set; }
public String Message { get; set; }
public virtual ICollection<Employee> Employees { get; set; }

员工

public Guid EmployeeId { get; set; }
public String Name { get; set; }
public virtual ICollection<Memo> Memos { get; set; }

使用Package Manager控制台更新数据库时,已在数据库中创建一个联结表。我使用以下代码行:
update-database -force -verbose

我有一个用于创建新备忘录的视图。可以在此处选择一个员工列表并将其添加到备忘录中。但是,填写此联结表并没有按计划进行。我认为这与我的存储库的设置有关。我创建了一个MemoRepository和一个EmployeeRepository。

我处理Memo创建的控制器如下:

MemoController

public class MemoController : Controller
{
    private IMemoRepository _memoRepository;
    private IEmployeeRepository _employeeRepository;

    public MemoController(IMemoRepository memoRepository, IEmployeeRepository employeeRepository) {
        _memoRepository = memoRepository;
        _employeeRepository = employeeRepository;
    }

    public ViewResult Create() {
        //Initializes MemoCreateViewModel here
        return View(model);
    }

    [HttpPost]
    public ActionResult Create(MemoCreateViewModel model) {
        if(!ModelState.IsValid)
            return RedirectToAction("Create");

        Guid employeeId;
        List<Guid> employeeIds = new List<Guid>();
        foreach (var id in model.SelectedEmployeeIds) {
            if (!Guid.TryParse(id, out employeeId)) {
                continue;
            }
            employeeIds.Add(employeeId);
        }
        var employees = _employeeRepository.GetEmployeesByIds(employeeIds);
        model.Memo.Employees = employees.ToList<Employee>();
        _memoRepository.SaveMemo(model.Memo);

        return RedirectToAction("List");
    }
}

备注存储库

public class EFMemoRepository : IMemoRepository
{
    private EFDbContext context;

    public EFMemoRepository(EFDbContext _context) {
        context = _context;
    }

    public IQueriable<Memo> Memos {
        return context.Memos;
    }

    public void SaveMemo(Memo memo) {
        if(memo.MemoId == Guid.Empty) {
            memo.MemoId = Guid.NewGuid();
            context.Memos.Add(memo); //error 1 here 
        } else {
            Memo dbEntry = context.Memos.Find(memo.MemoId);
            if(dbEntry != null) {
                dbEntry.Message = memo.Message;
                dbEntry.Employees = memo.Employees;
            }
        }
    context.SaveChanges(); //error 2 here
    }
}

插入时出现错误1:

IEntityChangeTracker的多个实例不能引用一个实体对象。

更新时出现错误2:

无法定义两个对象之间的关系,因为它们已附加到不同的ObjectContext对象。

我如何解决这个问题,我读了一些有关人们的话题,他们说这与使用不同的上下文有关,而其他人则说与它有关Attach(),但是我不知道如何在我的应用程序中解决这个问题。

请告诉我您是否需要更多信息。

注意:我省略了一些代码,以使其更易于阅读。当然可以根据需要添加代码。

您收到第一个错误,因为要添加传递到上下文的Memo对象。但是,使用另一个dbContext检索了添加到控制器内部备注对象中的雇员对象。要解决此问题,必须在两个操作之间共享db上下文,或者必须将Employee对象显式附加到当前上下文。

选项1:控制器代码

[HttpPost]
public ActionResult Create(MemoCreateViewModel model) {
    if(!ModelState.IsValid)
        return RedirectToAction("Create");

    Guid employeeId;
    List<Guid> employeeIds = new List<Guid>();
    foreach (var id in model.SelectedEmployeeIds) {
        if (!Guid.TryParse(id, out employeeId)) {
            continue;
        }
        employeeIds.Add(employeeId);
    }
    EFDbContext dbContext = new EFDbContext();//Note
    var employees = _employeeRepository.GetEmployeesByIds(dbContext, employeeIds);//Note the extra parameter
    model.Memo.Employees = employees.ToList<Employee>();
    _memoRepository.SaveMemo(dbContext,model.Memo);//Note the extra parameter

    return RedirectToAction("List");
}

EFMemoRepository类别代码:

public void SaveMemo(EFDbContext dbContext, Memo memo) 
{
    if(memo.MemoId == Guid.Empty) 
    {
        memo.MemoId = Guid.NewGuid();
        context.Memos.Add(memo); //error 1 here 
    } else 
    {
        Memo dbEntry = dbContext.Memos.Find(memo.MemoId);
        if(dbEntry != null) 
        {
            dbEntry.Message = memo.Message;
            for (int i = 0; i < dbEntry.Employees.Count; i++)/*Please note that if lazy loading is not True then this reference must explicitly be loaded*/
            {
              dbEntry.Employees.Remove(dbEntry.Employees.First());
            }
            foreach (var item in memo.Employees)
            {
                dbEntry.Employees.Add(item);
            }
           context.Entry(dbEntry).State = EntityState.Modified;                
        }
    }
    dbContext.SaveChanges(); //error 2 here
}

或者

选项2:

public void SaveMemo(Memo memo) 
{
    if(memo.MemoId == Guid.Empty) 
    {
        memo.MemoId = Guid.NewGuid();
        context.Memos.Add(memo); //error 1 here 
    } else 
    {
        Memo dbEntry = context.Memos.Find(memo.MemoId);
        if(dbEntry != null) 
        {
            dbEntry.Message = memo.Message;
            for (int i = 0; i < dbEntry.Employees.Count; i++)/*Please note that if lazy loading is not True then this reference must explicitly be loaded*/
            {
               dbEntry.Employees.Remove(dbEntry.Employees.First());
            }
            foreach (var item in memo.Employees)
            {
                dbEntry.Employees.Add(item);
            }   
            context.Entry(dbEntry).State = EntityState.Modified;              
        }
    }
    context.SaveChanges(); //error 2 here
}

我个人会选择选项1或类似的方式。

喊不清楚

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

活动记录协会一对多

来自分类Dev

休眠一对多自动插入ID

来自分类Dev

一对多插入错误的表

来自分类Dev

mysql加入一对多最后一条记录

来自分类Dev

一行一对多地获取每条记录

来自分类Dev

SQLAlchemy一对多,添加一条记录

来自分类Dev

以一对多关系插入新/更新现有记录

来自分类Dev

具有一对多关系的 Laravel 插入记录

来自分类Dev

如何在SQL Server中串联一对多记录

来自分类Dev

Flask-SQLAlchemy更新一对多记录

来自分类Dev

如何编写一对多映射记录的查询

来自分类Dev

一对多-更新序列-不删除/插入孩子

来自分类Dev

EntityFramework关系一对多(在此插入帮助)-渴望加载

来自分类Dev

插入遍历时ActiveRecord一对多更新错误

来自分类Dev

Hibernate:如何通过级联插入一对多孩子

来自分类Dev

多对多,一对多或多对一

来自分类Dev

插入一对多和多对一字段

来自分类Dev

对散点图;一对多

来自分类Dev

NHibernate <一对多>

来自分类Dev

与Kotlin一对多

来自分类Dev

一对多查询

来自分类Dev

单排一对多

来自分类Dev

Django一对多

来自分类Dev

一对多休眠

来自分类Dev

困扰一对多

来自分类Dev

如何在Android中具有一对一或一对多关系的对象化实体中插入记录

来自分类Dev

如何在Android中具有一对一或一对多关系的对象化实体中插入记录

来自分类Dev

一对多关系MySQL-仅获得一个多记录

来自分类Dev

插入实体间的Android一个一对多的关系