Я занимаюсь учебным курсом mvcmusicstore. Я заметил что-то при создании эшафота для менеджера альбомов (добавьте удаление).
Я хочу написать код элегантно, поэтому я ищу чистый способ написать это.
FYI я делаю магазин более общим:
Альбомы = Элементы
Жанры = Категории
Исполнитель = Бренд
Вот как извлекается индекс (сгенерированный MVC):
var items = db.Items.Include(i => i.Category).Include(i => i.Brand);
Вот как извлекается элемент для удаления:
Item item = db.Items.Find(id);
Первый возвращает все элементы и заполняет модели категорий и брендов внутри модели элементов. Второй, не заполняет категорию и бренд.
Как я могу написать второй для поиска и заполнить внутри (желательно в 1 строке)... теоретически - что-то вроде:
Item item = db.Items.Find(id).Include(i => i.Category).Include(i => i.Brand);
Сначала вам нужно использовать Include()
, а затем извлечь один объект из результирующего запроса:
Item item = db.Items
.Include(i => i.Category)
.Include(i => i.Brand)
.SingleOrDefault(x => x.ItemId == id);
...ToList().Find(id)
или ...SingleOrDefault()
вместо этого. Смотрите модифицированный ответ.
Ответ Dennis использует Include
и SingleOrDefault
. Последний отправляется в базу данных.
Альтернативой является использование Find
в сочетании с Load
для явной загрузки связанных объектов...
Ниже примера MSDN:
using (var context = new BloggingContext())
{
var post = context.Posts.Find(2);
// Load the blog related to a given post
context.Entry(post).Reference(p => p.Blog).Load();
// Load the blog related to a given post using a string
context.Entry(post).Reference("Blog").Load();
var blog = context.Blogs.Find(1);
// Load the posts related to a given blog
context.Entry(blog).Collection(p => p.Posts).Load();
// Load the posts related to a given blog
// using a string to specify the relationship
context.Entry(blog).Collection("Posts").Load();
}
Конечно, Find
немедленно возвращается без запроса в хранилище, если этот объект уже загружен контекстом.
Find
поэтому, если сущность присутствует, для самой сущности нет обхода в DB. НО, у вас будет туда-обратно для каждого отношения вы находитесь Load
ING, в то время как SingleOrDefault
комбинация с Include
нагрузок все в один присест.
Не работает для меня. Но я решил это, сделав вот так.
var item = db.Items
.Include(i => i.Category)
.Include(i => i.Brand)
.Where(x => x.ItemId == id)
.First();
Не знаю, хорошо ли это решение. Но другой, которого дал Деннис, дал мне ошибку bool в .SingleOrDefault(x => x.ItemId = id);
SingleOrDefault(x => x.ItemId = id)
только из-за неправильного одиночного =
вместо двойного ==
?