#c# #sql #entity-framework #migration #ef-core-6.0
#c# #sql #entity-framework #миграция #ef-core-6.0
Вопрос:
Я пытаюсь достичь много-много-отношений, но я получаю:
Дочерняя / зависимая сторона не может быть определена для отношения «один к одному» между ‘Artikel.Лагер и Лагер.Artikel’. Чтобы определить дочернюю / зависимую сторону отношения, настройте свойство внешнего ключа. Если эти навигации не должны быть частью одного и того же отношения, настройте их без указания обратного. См. http://go.microsoft.com/fwlink/?LinkId=724062 для получения более подробной информации.
ER:
Код:
#region Data
[Table("Lager")]
public class Lager
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; } = "";
public string Strasse { get; set; } = "";
public string PLZ { get; set; } = "";
public string Ort { get; set; } = "";
public Artikel Artikel { get; set; }
}
[Table("LagerArtikel")]
public class LagerArtikel
{
public Guid Id { get; set; } = Guid.NewGuid();
//[ForeignKey("Lager")]
//public Guid LagerId { get; set; }
//[ForeignKey("Artikel")]
//public Guid ArtikelId { get; set; }
public int Menge { get; set; }
public ICollection<Artikel> Artikels { get; set; }
public ICollection<Lager> Lagers { get; set; }
}
[Table("Artikel")]
public class Artikel
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; } = "";
public decimal EinkaufspreisNettoEuro { get; set; }
public Lager Lager { get; set; }
}
#endregion
#region Context
// => EF Core
/*
Add-Migration Initial -context _1_Testing.XDBContextTesting -o MigrationsXDBContextTestingMig
add-migration -Name A3 -Project compDatMVP -context _1_Testing.XDBContextTesting
Update-Database -context _1_Testing.XDBContextTesting
*/
public class XDBContextTesting : DbContext
{
public DbSet<Lager> Lager { get; set; }
public DbSet<LagerArtikel> LagerArtikel { get; set; }
public DbSet<Artikel> Artikel { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(new string(Konstanten.ConnectionString.Replace("#db#", "compDat__1__Testing")));
}
public XDBContextTesting() : base()
{
}
public XDBContextTesting(DbContextOptions<XDBContextTesting> options) : base(options)
{
}
}
#endregion
Что именно я пропустил?
Ответ №1:
Вы пропустили все «многие ко многим» 🙂
В лагере будет много артикелей, в то время как в Артикеле будет много лагеров.
public class Lager
{
[Key]
public int LagerId { get; set; }
// ...
public virtual ICollection<LagerArtikel> LagerArtikels { get; set; } = new List<LagerArtikel>();
}
public class Artikel
{
[Key]
public int ArtikelId { get; set; }
// ...
public virtual ICollection<LagerArtikel> LagerArtikels { get; set; } = new List<LagerArtikel>();
}
public class LagerArtikel
{
[Key]
public int LagerArtikelId {get; set;}
[ForeignKey("Lager")]
public int LagerId {get; set;}
[ForeignKey("Artikel")]
public int ArtikelId {get; set;}
// or just use a composite PK:
//[Key, Column(Order=1), ForeignKey("Lager")]
//public int LagerId {get; set;}
//[Key, Column(Order=2), ForeignKey("Artikel")]
//public int ArtikelId {get; set;}
public virtual Lager Lager { get; set; }
public virtual Artikel Artikel { get; set; }
public int Menge { get; set; }
}
Поскольку связывающий объект (LagerArtikel) будет иметь дополнительные свойства, такие как Menge, вам необходимо использовать ссылку на этот объект. Если вы просто хотите, чтобы таблица LagerArtikel содержала только LagerId и ArtikelId в качестве составной PK для представления ссылки «многие ко многим», с EF6 и EF Core 5 вы могли бы отказаться от объекта LagerArtikel, и у Лагера могла быть коллекция артикелей, в то время как у Artikel есть коллекция лагеров, где EFможет управлять отношением и соответствующей таблицей без дополнительного объекта.
Подумайте об этом с точки зрения таблицы. Что бы вы поместили в таблицу LagerArtikel? У него были бы LagerId и ArtikelId, он не может хранить много лагеров и много артикелей в одной строке, вместо этого каждая строка в этой таблице связывает артикель с лагером. Многие строки будут иметь общий идентификатор ArtikelId, и многие строки будут иметь общий идентификатор LagerId.
Ответ №2:
Вам нужно заменить public Artikel Artikel { get; set; }
в Lager
классе, а также заменить public Lager Lager { get; set; }
в Artikel
классе.
Вы бы предпочли добавить public LagerArtikel LagerArtikel { get; set; }
в оба класса