У меня есть существующая база данных SQL, которая очень старая и схема не очень хорошая, но я не могу ее изменить, мне приходится с этим жить.
Я новичок в Entity Framework ииспользуя EF Core 3 , чтобы попытаться создать базовое приложение CRUD.У меня трудности с отношениями «многие ко многим».
В приведенном ниже примере я приведу сокращенное / фиктивное представление сценария.
Итак, вБД У меня есть две таблицы [People] и [The_Cars], и есть таблица «связывания», которая называется [People__The_Cars].Да, ужасные имена таблиц ....
Определение каждой таблицы следующее:
CREATE TABLE [dbo].[People](
[PeopleID] [varchar](10) NOT NULL),
[Name] [varchar](255) NOT NULL)
Это первичный ключ PeopleID
CREATE TABLE [dbo].[The_Cars](
[car_id] [int] NOT NULL,
[car_name] [varchar](255) NOT NULL)
ThisНЕ имеет первичного ключа ....
CREATE TABLE [dbo].[People__The_Cars](
[People__The_Cars_ID] [int] NOT NULL,
[car_name] [nvarchar](255) NOT NULL,
[PeopleID] [nvarchar](255) NOT NULL,
У него есть первичный ключ, но нет внешних ключей.Автомобиль "ФК" идет по названию, а не по удостоверению личности.И типы данных не совпадают [PeopleID is varchar (10) в таблице [People], но nvarchar (255) в этой таблице ссылок].Также используйте varchar vs nvarchar.
В C # я создал несколько классов для представления их с приведенными именами:
Для [Люди]
public class People
{
[StringLength(10)]
[Required]
public string ID{ get; set; }
[StringLength(255)]
[Required]
public string Name { get; set; }
public ICollection<People__The_Cars> PeopleCars{ get; set; }
}
для[The_Cars]
public class The_Cars
{
[Required]
public int Id{ get; set; }
[StringLength(255)]
[Required]
public string Name { get; set; }
public ICollection<People__The_Cars> PeopleCars{ get; set; }
}
для таблицы ссылок
public class People__The_Cars
{
[Required]
public int Id{ get; set; }
[StringLength(10)]
[Required]
public string PeopleId { get; set; }
[StringLength(255)]
[Required]
public string CarName { get; set; }
public People Person{ get; set; }
public The_Cars Car{ get; set; }
}
(аннотации данных отражают типы данных первичной таблицы)
Теперь в классе контекста данных
public class MyContext : DbContext
{
public OpdxDestinationsContext(DbContextOptions<MyContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<People>(e =>
{
e.HasKey(i => i.Id);
e.Property(i => i.Id).HasColumnName("PeopleID");
});
modelBuilder
.Entity<People__The_Cars>(e =>
{
e.HasKey(i => i.Name);
e.Property(i => i.Id).HasColumnName("People__The_Cars_ID");
e.Property(i => i.CarName).HasColumnName("car_name");
});
modelBuilder
.Entity<Software_Vendor_Destinations>(e =>
{
e.HasKey(i => new {i.PeopleId, i.CarName });
e.Property(i => i.Id).HasColumnName("Software_Vendor_Destinations_Id");
e.Property(i => i.CarName).HasColumnName("car_name");
e.Property(i => i.DestinationId).HasColumnName("PeopleID");
});
modelBuilder.Entity<People__The_Cars>()
.HasOne(x => x.People)
.WithMany(m => m.PeopleCars)
.HasForeignKey(x => x.CarName);
modelBuilder.Entity<People__The_Cars>()
.HasOne(x => x.Car)
.WithMany(m => m.PeopleCars)
.HasForeignKey(x => x.PeopleId);
base.OnModelCreating(modelBuilder);
}
public DbSet<People> People{ get; set; }
public DbSet<Cars> Cars{ get; set; }
}
Итак, несколько вопросов.
- Я использовал «HasKey» для таблиц без ключей.Они должны сделать.Это плохая практика, или я должен быть правдивым и использовать HasNoKey, когда кто-то отсутствует.
- Как мне тогда установить отношение «многие ко многим» с этими объектами?«Таблица связей» на самом деле предназначена для определения отношения «многие к одному ко многим» в БД и не кажется мне чем-то, что я хочу раскрыть в своих сущностях.
Так много всего, что нужно изучить...