ASP.Net Entity Framework много-много обновлений не работает - PullRequest
0 голосов
/ 20 ноября 2018

Я могу добавить новое агентство с выбранными секторами, но когда мне нужно изменить существующее агентство, чтобы добавить или удалить существующие сектора, изменения не сохраняются для отношений.

Мой метод 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 получает идентификаторы выбранного сектора из списка.Когда я отлаживаю, я вижу, что они обнаруживаются, просто они не сохраняются в обновленном состоянии.

В модели моего агентства секторы представлены в виде коллекции.Вот часть этого.

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 голосов
/ 23 ноября 2018

Я исправил это, очистив базу данных соединений от любых отношений в начале сообщения и переделав отношения.Код:

[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";

и моего запроса для очистки отношенияis;

var con = new SqlConnection(ConfigurationManager.ConnectionStrings["Delete"].ConnectionString);           
    con.Open();
    var cmd = new SqlCommand("Delete from " + dbTable  +
                                    " where " + dbTable + ".agencyid = " + agency.id, con);
    cmd.ExecuteNonQuery();
    con.Close();

Я постарался сделать не столько жесткий код, сколько смог, чтобы сделать его многоразовым для других таблиц.Возможно, это можно улучшить, но пока это работает.

0 голосов
/ 20 ноября 2018

Не уверен, собирается ли это исправить это для вас, но, возможно, оно того стоит.Я бы попытался просто добавить элементы в базу данных вместо того, чтобы пытаться обнаружить изменения через состояние.

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

РЕДАКТИРОВАТЬ: Просто понял, что это не вернет элементы, которые должны быть удалены из базы данных.Я хотел бы попробовать код, чтобы увидеть, работает ли он, а затем попытаться заставить его удалить после.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...