#asp.net #sql #asp.net-mvc #entity-framework #many-to-many
#asp.net #sql #asp.net-mvc #entity-framework #многие ко многим
Вопрос:
У меня проблема с использованием EF 4.1 и отношений «многие ко многим». Я решил использовать подход database first (хотя у меня возникла та же проблема с подходом code first), и я создал модель базы данных:
У меня есть отношения «многие ко многим» между таблицами изображений и тегов. В БД она создается как новая таблица с именем «PictureTag» с полями «Picture_Id» и «Tag_Id».
Я добавляю данные в свою базу данных с помощью следующего фрагмента кода:
if (tags != null)
{
foreach (HtmlNode tagNode in tags)
{
string tagString = tagNode.InnerText.Remove(0, 1);
Tag tag;
if (db.Tags.Any(q => q.TagName == tagString))
{
tag = db.Tags.Single(q => q.TagName == tagString);
}
else
{
tag = new Tag { TagName = tagString };
}
pic.Tags.Add(tag);
}
}
List<DbEntityValidationResult> list = db.GetValidationErrors().ToList();
db.Pictures.Add(pic);
db.SaveChanges();
Это, конечно, всего лишь часть моего кода. Это часть моей функции поиска. Код работает нормально, не генерирует никаких ошибок и работает в одном контексте БД.
После выполнения этой функции я могу видеть данные в своей БД, все три изображения, теги и объекты в таблице PictureTag.
Тем не менее, когда я пытаюсь поместить в свой просмотр изображения и теги, соответствующие этому изображению, я не вижу никаких тегов. Например, ни к одному из изображений не было прикреплено никаких тегов. Я знаю, что это неправда, потому что я вижу данные в своей БД, поэтому я не знаю, что не так…
На мой взгляд, это код:
@model IEnumerable<SikSolution.Picture>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@foreach (var item in Model)
{
<div>
<img src="@item.Link" alt="@item.Name" />
<br />
<span>
Tags: @foreach (var tag in item.Tags)
{
Html.Label(tag.TagName ", ");
}
</span>
</div>
}
Я действительно не знаю, что не так… Я был бы признателен за любой совет или указание мне в правильном направлении.
Спасибо!
Ответ №1:
Возможное объяснение заключается в том, что вы не используете отложенную загрузку, а также не загружали свою Picture
коллекцию, включая связанные теги (быстрая загрузка). Это должно выглядеть так:
//...
var pictures = db.Pictures.Include("Tags") // or Include(p => p.Tags) in EF 4.1
.Where(...)
.ToList();
return View(pictures);
Комментарии:
1. Большое вам спасибо, я понятия не имел, что теперь мне нужно явно сообщить моей коллекции, что я хочу что-то к ней прикрепить. Это новое в EF 4.1?
2. @Tromax: Нет, это не ново. В EF всегда было три способа загрузки свойств навигации: отложенная загрузка, быстрая загрузка и явная загрузка. Это не изменилось с EF 4.1. Вот обзор об этом: blogs.msdn.com/b/adonet/archive/2011/01/31/… Если вы не хотите использовать
Include
в своих запросах, вы можете использовать отложенную загрузку, тогда загрузка произойдет «автоматически», и ваш исходный код будет работать. Однако отложенная загрузка приводит к многократным обходам в БД.