Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF:使用添加、删除或未更改的子实体更新实体(多对多关系)_C#_Entity Framework_Many To Many - Fatal编程技术网

C# EF:使用添加、删除或未更改的子实体更新实体(多对多关系)

C# EF:使用添加、删除或未更改的子实体更新实体(多对多关系),c#,entity-framework,many-to-many,C#,Entity Framework,Many To Many,这是我第一次在asp.net mvc应用程序中使用EF。在过去的两天里,我阅读了类似的问题和例子,但到目前为止,我还没有完全理解我必须做什么 我有两个具有多对多关系的实体 型号: [Table("Unit")] public class UnitEntity { [Required] [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; }

这是我第一次在asp.net mvc应用程序中使用EF。在过去的两天里,我阅读了类似的问题和例子,但到目前为止,我还没有完全理解我必须做什么

我有两个具有多对多关系的实体

型号:

[Table("Unit")]
public class UnitEntity
{
    [Required]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public UnitType Type { get; set; }

    [StringLength(255)]
    public string Title { get; set; }

    ///some other properties

    public virtual ICollection<UserEntity> Users { get; set; }
}

[Table("User")]
public class UserEntity
{
    [StringLength(255)]
    public string Id { get; set; }

    [Required]
    public string UserName { get; set; }

    [Required]
    public string Email { get; set; }


    public int Status { get; set; }

    // some other properties

    public virtual ICollection<UnitEntity> DepartmentUnits { get; set; }
}

我需要更新我的UserDepartments表(请参见上面的model builder),以便删除删除的、添加新的和保留特定用户的现有部门单位。上述操作不起作用,我迷路了,非常感谢您的帮助。

只要将
dataContext
变量生存时间限定为单个
UpdateUser
操作,您就可以让EF change tracker通过从数据库加载目标实体(包括相关集合)为您完成大部分工作,然后简单地将其替换为从传递实体的相应集合创建的存根实体列表:

public void UpdateUser(UserEntity entity)
{
    // Load the exiting entity from the db, including the collection
    var dbEntity = this.dataContext.Users
        .Include(e => e.DepartmentUnits)
        .FirstOrDefault(e => e.Id == entity.Id);

    if (dbEntity == null)
        throw new NullReferenceException("User not found");

    // Update the master information
    this.dataContext.Entry(dbEntity).CurrentValues.SetValues(entity);

    // Replace the collection with stubs created from the source collection
    dbEntity.DepartmentUnits = entity.DepartmentUnits.Select(e => new UnitEntity { Id = e.Id }).ToList();

    // And that's all - EF change tracker will detect added/removed/unchanged links (and changed master properties) for you.
    // Just commit the changes and you are done.
    this.dataContext.SaveChanges();
}
请注意,这在EF6中有效。EF Core目前需要更多与您尝试过的类似的手动操作。

工作代码:

public void UpdateUser(UserEntity entity)
    {

        var updentity = this.dataContext.Users.Include(e => e.DepartmentUnits).FirstOrDefault(e => e.Id == entity.Id);


        if (updentity == null)
            throw new NullReferenceException("User not found");


        updentity.Status = entity.Status;

        updentity.DepartmentUnits = entity.DepartmentUnits.Select(e => this.dataContext.Units.Find(e.Id)).ToList();


        try
        {
            this.dataContext.SaveChanges();

        }
        catch (Exception)
        {
            throw new Exception("Update problem");

FWIW,此行:
this.dataContext.Entry(dbEntity).CurrentValues.SetValues(entity)引发实体处于不同上下文中的异常。此行:
dbEntity.DepartmentUnits=entity.DepartmentUnits.Select(e=>newunitentity{Id=e.Id}).ToList()使用空值向Unit表中添加新行,并使用实际不存在的UnitId向UserDepartments表中添加条目。然而,你解决了我的问题,因为你让我用另一种方式思考。非常感谢,我将把我的工作方案放在下面。
public void UpdateUser(UserEntity entity)
    {
        var updentity = this.dataContext.Users.Find(entity.Id);

        if (updentity == null)
            throw new NullReferenceException("User not found");


        updentity.Status = entity.Status;

        var newUnitIds = entity.DepartmentUnits.Select(u => u.Id);
        var existingUnitIds = updentity.DepartmentUnits.Select(u => u.Id);

        updentity.DepartmentUnits.Where(u => !newUnitIds.Contains(u.Id)).ToList().ForEach(d => updentity.DepartmentUnits.Remove(d));
        entity.DepartmentUnits.Where(u => newUnitIds.Except(existingUnitIds).Contains(u.Id)).ToList().ForEach(d => updentity.DepartmentUnits.Add(d));


        this.dataContext.Entry(updentity).State =  EntityState.Modified;


        foreach (var deptentity in updentity.DepartmentUnits)
        {
            if(newUnitIds.Contains(deptentity.Id))
            {
                this.dataContext.Entry(deptentity).State = EntityState.Added;
            }
            if(existingUnitIds.Contains(deptentity.Id))
            {
                this.dataContext.Entry(deptentity).State = EntityState.Unchanged;
            }
        }


        try
        {
            this.dataContext.SaveChanges();

        }
        catch (Exception)
        {
            throw new Exception("Update problem");
        }

    }
public void UpdateUser(UserEntity entity)
{
    // Load the exiting entity from the db, including the collection
    var dbEntity = this.dataContext.Users
        .Include(e => e.DepartmentUnits)
        .FirstOrDefault(e => e.Id == entity.Id);

    if (dbEntity == null)
        throw new NullReferenceException("User not found");

    // Update the master information
    this.dataContext.Entry(dbEntity).CurrentValues.SetValues(entity);

    // Replace the collection with stubs created from the source collection
    dbEntity.DepartmentUnits = entity.DepartmentUnits.Select(e => new UnitEntity { Id = e.Id }).ToList();

    // And that's all - EF change tracker will detect added/removed/unchanged links (and changed master properties) for you.
    // Just commit the changes and you are done.
    this.dataContext.SaveChanges();
}
public void UpdateUser(UserEntity entity)
    {

        var updentity = this.dataContext.Users.Include(e => e.DepartmentUnits).FirstOrDefault(e => e.Id == entity.Id);


        if (updentity == null)
            throw new NullReferenceException("User not found");


        updentity.Status = entity.Status;

        updentity.DepartmentUnits = entity.DepartmentUnits.Select(e => this.dataContext.Units.Find(e.Id)).ToList();


        try
        {
            this.dataContext.SaveChanges();

        }
        catch (Exception)
        {
            throw new Exception("Update problem");