Как сначала указать составной ключ в коде Entity Framework - PullRequest
3 голосов
/ 11 ноября 2010

У меня есть быстрый вопрос о настройке отображений между [Order Details], [Products] и [Orders] в базе данных Northwind.

[Order Details] не имеет первичного ключа и выглядит следующим образом

[Order Details]
OrderId (int)
ProductId (int)
...

Итак, мой вопрос: как (и могу ли я) настроить мой класс OrderDetails для такой работы?

public class OrderDetails
{
    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
    public Decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public Decimal Discount { get; set; }
}

Мой контекст данных выглядит следующим образом

public class NorthwindDb : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetails> OrderDetails { get; set; }
    public DbSet<Customer> Customers { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new OrderDetailsConfiguration());
    }

    public static void InitializeBecauseOfThatWeirdMetaDataThingThatIDontUnderstandYet()
    {
        Database.SetInitializer<NorthwindDb>(null);
    }

}

И мой OrderDetailsConfiguration (пустой, потому что я не знаю, что я делаю)

public class OrderDetailsConfiguration : EntityConfiguration<OrderDetails>
{
    public OrderDetailsConfiguration()
    {
        //HasKey(x => x.Order.OrderId);
        //HasKey(x => x.Product.ProductId);
    }
}

Любые намеки или идеи будут великолепны.

Ответы [ 2 ]

4 голосов
/ 11 ноября 2010

Сначала вы должны явно указать PK и FK внутри OrderDetails class:

public class OrderDetails 
{        
    public int OrderID { get; set; }
    public int ProductID { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }

    public Decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public Decimal Discount { get; set; }
}

Затем с помощью следующего кода вы можете указать PK для OrderDetailsConfiguration класса:
(Обратите внимание, что в базе данных Northwind и OrderID и ProductID являются PK для OrderDetails таблицы).

public class OrderDetailsConfiguration : EntityConfiguration<OrderDetails> 
{
    public OrderDetailsConfiguration() 
    {
        HasKey(od => new 
        {
            od.ProductID,
            od.OrderID
        });
    }
}

А также вы можете использовать стратегию RecreateDatabaseIfModelChanges , чтобы принудительно создавать базу данных при каждом изменении модели класса:

Database.SetInitializer<NorthwindDb>(
        new RecreateDatabaseIfModelChanges<NorthwindDb>());

Интересно отметить, что после внесения этих изменений EF автоматически выведет FK из класса OrderDetails и создаст связи с таблицей Orders и Products на OrderID и ProductID на основе Условных обозначений для Code First:

Code First будет заключать, что любое свойство с именами <navigation property name><primary key property name> (т.е. ProductsProductID), <principal class name><primary key property name> (т.е. ProductProductID) или <primary key property name> (т.е. ProductID) с тем же типом данных, что и первичный ключ, представляет внешний ключ для отношения. Если найдено несколько совпадений, приоритет отдается в порядке, указанном выше. При обнаружении внешнего ключа регистр не учитывается.

1 голос
/ 22 июня 2015

Пометить ключевые поля атрибутом [Key].Вам нужно будет добавить [Столбец (Порядок = x)] в случае составных ключей, x = 0, 1, 2, ... Нумерация может начинаться с любого номера https://msdn.microsoft.com/en-us/data/jj591583.aspx

...