#c# #ef-core-2.2 #owned-types
#c# #ef-core-2.2 #принадлежащие типы
Вопрос:
У меня есть модель предметной области с коллекцией принадлежащих типов. Когда я пытаюсь добавить более одного объекта в коллекцию ownedtyped? Я получаю исключение:
Система.Исключение InvalidOperationException: ‘Экземпляр объекта типа ‘ChildItem’ не может быть отслежен, поскольку другой экземпляр со значением ключа ‘{NameID: -2147482647, Id: 0}’ уже отслеживается. При замене принадлежащих объектов измените свойства без изменения экземпляра или сначала отсоедините предыдущую запись принадлежащего объекта.’
Как это можно решить?
ОБНОВЛЕНО
Классы моего домена:
public class Parent
{
public int Id { get; set; }
public Child Name { get; set; }
public Child ShortName { get; set; }
}
public class Child
{
public List<ChildItem> Items { get; set; }
}
public class ChildItem
{
public string Text { get; set; }
public string Language { get; set; }
}
Мой DbContext:
public class ApplicationContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>()
.OwnsOne(c => c.Name, d =>
{
d.OwnsMany(c => c.Items, a =>
{
a.HasForeignKey("NameId");
a.Property<int>("Id");
a.HasKey("NameId", "Id");
a.ToTable("ParentNameItems");
})
.ToTable("ParentName");
})
.ToTable("Parent");
modelBuilder.Entity<Parent>()
.OwnsOne(c => c.ShortName, d =>
{
d.OwnsMany(c => c.Items, a =>
{
a.HasForeignKey("NameId");
a.Property<int>("Id");
a.HasKey("NameId", "Id");
a.ToTable("ParentShortNameItems");
})
.ToTable("ParentShortName");
})
.ToTable("Parent");
}
}
Использование:
static void Main(string[] args)
{
var context = new ApplicationContext();
var parent = new Parent()
{
Name = new Child()
{
Items = new List<ChildItem>()
{
new ChildItem() { Text = "First value", Language = "en-en"},
new ChildItem() { Text = "Second value", Language = "en-en"}
}
},
ShortName = new Child()
{
Items = new List<ChildItem>()
{
new ChildItem() { Text = "First short value", Language = "en-en"},
new ChildItem() { Text = "Second short value", Language = "en-en"}
}
}
};
context.Set<Parent>().Add(parent);
context.SaveChanges();
}
Ответ №1:
Ну, во-первых, ваши классы не имеют смысла. Во всяком случае, это должно быть
public class Parent
{
public int Id { get; set; }
public List<Child> Children { get; set; }
}
у родителя должно быть много дочерних элементов (или, возможно, ни одного, может быть, пустой список?). А как насчет имени и идентификатора дочернего элемента, разве у него нет по одному из них? также, возможно, родительский идентификатор, может быть, что-то вроде
public class Child
{
public virtual List<ChildItem> Items { get; set; } //why virtual? you planning to inherit?
public string Name {get; set; }
public int Id {get; set; }
public int ParentId {get; set; }
}
Я должен думать, что это выглядит немного лучше. В базе данных должны быть соответствующие таблицы. и давайте будем честны, автоматическое создание EF (Entity Framework) сделает 99% работы за вас, поэтому, пожалуйста, используйте его.
Комментарии:
1. Спасибо за быстрый ответ! Чтобы быть ближе к моей реальной ситуации, я внес некоторые обновления в код.
Ответ №2:
Проблема решена. Это было в строке
a.HasKey("NameId", "Id");
в OnModelCreating
методе.
Я использовал пример, где было написано о настройке коллекций принадлежащих типов.
После удаления поля «NameID» из определения ключа
a.HasKey("Id");
теперь все работает нормально.