ASP.Net实体框架多对多更新无法正常工作

时间:2018-11-20 16:37:39

标签: c# asp.net-mvc entity-framework

我可以添加具有所选部门的新代理,但是当我修改现有代理以添加或删除现有部门时,更改不会保存到该关系中。

我的POST方法

public ActionResult AddOrEdit(Agency agency, string[] selectedOptions)
{
        if (agency.id == 0)
        {
            agency.id = _db.Agencies.Count() + 1;

            UpdateAgencySectors(selectedOptions, agency);
            _db.Agencies.Add(agency);
            _db.SaveChanges();
            return Json(new {success = true, message = "Saved successfully"}, JsonRequestBehavior.AllowGet);
        }

        agency.lastupdated = DateTime.Now;
        UpdateAgencySectors(selectedOptions, agency);
        _db.Entry(agency).State = EntityState.Modified;
        _db.SaveChanges();

        return Json(new {success = true, message = "Updated successfully"}, JsonRequestBehavior.AllowGet);
}

我的更新扇区方法

private void UpdateAgencySectors(string[] selectedOptions, Agency agency)
{
        if (selectedOptions == null)
        {
            return;
        }

        var selectedOptionsHs = new HashSet<string>(selectedOptions);
        var agencySectors = new HashSet<int>(agency.Sectors.Select(b => b.id));

        foreach (var sector in _db.Sectors)
        {
            if (selectedOptionsHs.Contains(sector.id.ToString()))
            {
                if (!agencySectors.Contains(sector.id))
                {
                   agency.Sectors.Add(sector);
                }
            }
            else
            {
                if (agencySectors.Contains(sector.id))
                {
                    agency.Sectors.Remove(sector);
                }
            }
        }
}

selectedOptions数组从列表框中获取所选扇区的ID。调试时,可以看到它们被检测到,只是它们没有保存到更新状态。

我的代理商模型将部门作为集合。这是其中的一部分。

public partial class Agency
{
    public Agency()
    {
        this.Sectors = new HashSet<Sector>();
    }

    public int id { get; set; }
    public virtual ICollection<Sector> Sectors { get; set; }
}

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

不知道这是否可以为您解决,但是值得一试。我会尝试将项目添加到数据库中,而不是尝试通过状态检测更改。

public ActionResult AddOrEdit(Agency agency, string[] selectedOptions)
{
    if (agency.id == 0)
    {
        agency.id = _db.Agencies.Count() + 1;

        UpdateAgencySectors(selectedOptions, agency);
        _db.Agencies.Add(agency);
        _db.SaveChanges();
        return Json(new {success = true, message = "Saved successfully"}, JsonRequestBehavior.AllowGet);
    }

    agency.lastupdated = DateTime.Now;
    _db.Sectors.AddRange(GetAgencySectors(selectedOptions, agency));
    _db.SaveChanges();
    return Json(new {success = true, message = "Updated successfully"}, JsonRequestBehavior.AllowGet);
}

private ICollection<Sector> UpdateAgencySectors(string[] selectedOptions, Agency agency)
{
    List<Sector> sectors = new List<Sector>();

    if (selectedOptions == null)
    {
        return;
    }

    var selectedOptionsHs = new HashSet<string>(selectedOptions);
    var agencySectors = new HashSet<int>(agency.Sectors.Select(b => b.id));
    foreach (var sector in _db.Sectors)
    {
        if (selectedOptionsHs.Contains(sector.id.ToString()))
        {
            if (!agencySectors.Contains(sector.id))
            {
               sectors.Add(sector);
            }
        }
        else
        {
            if (agencySectors.Contains(sector.id))
            {
                sectors.Remove(sector);
            }
        }
    }
    return sectors;
}

编辑:刚刚意识到这不会返回需要从数据库中删除的项目。我会尝试该代码以查看其是否有效,然后尝试将其删除。

答案 1 :(得分:0)

我已通过在帖子开始时清除联接数据库中的任何关系并重做关系来解决此问题。代码是;

Lambda = np.zeros((6,7))

您可以在此处看到我要传递要清除的表的名称

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddOrEdit(Agency agency, string[] selectedOptions)
    {
        var dbTable = "AgencySector";

        if (agency.id == 0)
        {
            agency.created = DateTime.Now;
            agency.createdby = 1;
            agency.createdbytype = "A";
            agency.lastupdated = DateTime.Now;
            agency.lastupdatedby = 1;
            agency.lastupdatedbytype = "A";
            agency.deleted = false;

            UpdateAgencySectors(selectedOptions, agency, dbTable);
            _db.Agencies.Add(agency);
            _db.SaveChanges();
            return Json(new {success = true, message = "Saved successfully"}, JsonRequestBehavior.AllowGet);
        }

        _db.Agencies.Attach(agency); //attaches chosen agency

        UpdateAgencySectors(selectedOptions, agency, dbTable);
        _db.Entry(agency).CurrentValues.SetValues(typeof(AgencySectorViewModel));
        //adds relationship found in UpdateAgencySectors

        agency.lastupdated = DateTime.Now; //updates modified time
        _db.Entry(agency).State = EntityState.Modified;         
        _db.SaveChanges();

        return Json(new {success = true, message = "Updated successfully"}, JsonRequestBehavior.AllowGet);
    }

    private void UpdateAgencySectors(string[] selectedOptions, Agency agency, string dbTable)
    {
        var con = new SqlConnection(ConfigurationManager.ConnectionStrings["Delete"].ConnectionString);           
        con.Open();
        var cmd = new SqlCommand("Delete from " + dbTable  +
                                        " where " + dbTable + " = " + agency.id, con);
        cmd.ExecuteNonQuery();
        con.Close();

        if (selectedOptions == null)
        {
            return;
        }

        var selectedOptionsHs = new HashSet<string>(selectedOptions);
        var agencySectors = new HashSet<int>
            (agency.Sectors.Select(b => b.id));

        foreach (var sector in _db.Sectors)
        {
            if (!selectedOptionsHs.Contains(sector.id.ToString())) continue;
            if (!agencySectors.Contains(sector.id))
            {
                agency.Sectors.Add(sector);
            }
        }
    }

我要清除的查询是;

var dbTable = "AgencySector";

到目前为止,我已确保不会对我进行尽可能多的硬编码,以使其可重用于其他表。可能可以改进,但目前可以。