Entity Framework 4.1.Обновление отношений «многие ко многим».Это правильный путь? - PullRequest
2 голосов
/ 07 декабря 2011

Код ниже работает, однако, я подозреваю, что я что-то упустил.Есть ли «лучший» способ?

    private void UpdateNew(MarketProduct marketproduct)
    {
        context.MarketCategories.Load();
        MarketProduct dbProd = context.MarketProducts.Find(marketproduct.Id);
        dbProd.Categories.Clear();
        foreach (var c in marketproduct.Categories ?? Enumerable.Empty<MarketCategory>())
        {
            var cc = context.MarketCategories.Find(c.Id);
            dbProd.Categories.Add(cc);
        }
        context.Entry(dbProd).CurrentValues.SetValues(marketproduct);
    }

Я думал, что можно было бы сделать это без использования Find

Ответы [ 2 ]

1 голос
/ 07 декабря 2011

У вас есть три запроса к базе данных: 1) context.MarketCategories.Load() (надеюсь, таблица категорий мала, в противном случае это будет неисполнение при загрузке всей таблицы в память), 2) ...Find и 3) dbProd.Categories.Clear(): Здесь должна быть отложенная загрузка, иначе это приведет к сбою, потому что dbProd.Categories будет null.

Альтернативой обновлению с помощью одного запроса к базе данных является:

private void UpdateNew(MarketProduct marketproduct)
{
    MarketProduct dbProd = context.MarketProducts
        .Include(p => p.Categories)
        .Single(p => p.Id == marketproduct.Id);

    var categories = marketproduct.Categories 
                     ?? Enumerable.Empty<MarketCategory>();
    foreach (var category in categories)
    {
        if (!dbProd.Categories.Any(c => c.Id == category.Id))
        {
            // means: category is new
            context.MarketCategories.Attach(category);
            dbProd.Categories.Add(category);
        }
    }
    foreach (var category in dbProd.Categories.ToList())
    {
        if (!categories.Any(c => c.Id == category.Id))
            // means: category has been removed
            dbProd.Categories.Remove(category);
    }

    context.Entry(dbProd).CurrentValues.SetValues(marketproduct);

    // context.SaveChanges() somewhere
}
0 голосов
/ 07 декабря 2011

Полагаю, вы могли бы просто сделать это:

var dbProd = context.MarketProducts.Find(marketproduct.Id);
dbProd.Categories = dbProd.Categories
    .Union(marketproduct.Categories).ToList();

context.SaveChanges();

Вызов Union() сохранит все существующие продукты, добавит новые и обновит перекрывающиеся. Поскольку ваше свойство навигации Categories, вероятно, определено как ICollection<Category>, вы должны использовать метод расширения ToList() во время назначения.

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