Код элемента Entity Framework Сначала: добавление ко многим отношениям по ID
У меня есть отношение "Много-ко-многим", определенное следующим образом:
public class Post
{
//NOT SHOWN: Other properties
public virtual ICollection<Tag> Tags { get; set; }
}
Все примеры, которые я вижу, добавят к отношениям "многие ко многим":
//Get the tag with ID of 1
var tag = context.Tags.Find(1);
// associate tag with ID of 1 with myPost
myPost.Tags.Add(tag);
Но это кажется утомительным/неэффективным, если я просто знаю идентификатор тега (ов), который я хотел бы связать с моим сообщением.
В идеале я просто хотел бы открыть List<int> TagIds
на моей почтовой сущности и иметь возможность добавлять теги, добавив теги идентификаторов в список, но мне не удалось определить, возможно ли это с использованием EF Code First.
Итог: какой лучший способ добавить элементы ко многим отношениям, учитывая, что у меня есть только те объекты, которые я хочу связать. (например, если у меня есть список идентификаторов тегов, какой лучший способ связать эти теги с сообщением?)
Ответы
Ответ 1
Используйте такой код:
// Existing post without loading it from the database
var myPost = new Post() { Id = ... };
context.Posts.Attach(post);
// For each id of existing tag
foreach (int tagId in someExistingTagIds)
{
var tag = new Tag() { Id = tagId };
context.Tags.Attach(tag);
// Make a new relation
post.Tags.Add(tag);
}
context.SaveChanges();
Это позволит вам создать отношение MN к существующим объектам, не загружая ничего из базы данных. Вам просто нужно знать идентификаторы существующих объектов.
Ответ 2
Надеюсь, кто-то с большим опытом работы в EF сможет вам помочь, но если бы я был в этой ситуации, я бы сам моделировал отношения MM (так, моделируя таблицу ссылок). Таким образом, вы можете
myPost.PostTags.Add(new PostTagLink(){
TagID = 1
});
Но тогда вам придется иметь дело с дополнительным объектом таблицы ссылок. На обратной стороне, если вы собираетесь добавить дополнительные свойства в отношения, вам все равно придется это делать.
Если есть лучший способ обойти это, я тоже хотел бы знать.
Ответ 3
Почему вы говорите, что это неэффективно. Если вы объявите его Виртуальным, он не будет загружен до тех пор, пока вы не получите доступ к нему при включении ленивой загрузки. Скажем, если у вас есть список значений Id. Затем, когда вы хотите загрузить весь список, вам нужно вызвать getById
для всех значений. Это очень неэффективно, чем использование ленивой загрузки.