0
votes

I have the following classes:

public class GoodsIssueProcess
{

    [Key, Column(Order = 1), MaxLength(128)]
    public string DeliveryNote { get; set; }

    [Key, Column(Order = 2)]
    public Product Product { get; set; }
}

public class Product
{
    // the unique ID of the product
    [Key]
    public int Id { get; set; }

    [Required, MaxLength(36)]
    [Index("IX_ArticleNumber", 1, IsUnique = true)]
    public string ArticleNumber { get; set; }
}

(abbreviated for readability)

As you can see, the GoodsIssueProcess consists of a Product and a delivery note code (basically just a number). According to the specification of the "Key" keyword I would expect to get a composite primary key for ProductId and DeliveryNote. Yet, what I get is a normal Primary Key for DeliveryNote. The Product column even gets the Nullable attribute and a foreign key relationship to the Product table (which is fine).

Do you have any ideas what I am doing wrong? I have also tried assigning the following:

[Key, Column(Order = 2), ForeignKey("Product")]
public int ProductId { get; set; }
public virtual Product Product { get; set; }

The result was the same database layout (only a single primary key, no composite key). I'm working on EF 6.0 and MSSQL Server 2012.

EDIT: Stop! - Apparently version #2 works (the one with public int ProductId). Yet, shouldn't the first version work as well?

1
The first version does not work. If you don't like to see ProductId property you can use a private backing field and fluent interface to map it and to set the key (the class containing the fluent interface map has to be an inner class of GoodsIssueProcess) - bubi
I don't really care if I see the ProductId but I would like to understand why the first version doesn't work. Is it because Product is no int/string which can be used for a primary key? - Tom L.
I don't know if EF likes to see navigation properties declared as key. I'm not too experienced with data annotations, but I think it might just ignore those key requirements on navigation properties. - DevilSuichiro
A Key should be a column in database. Navigation Properties are not a column in database. I believe that's why it doesn't work - Fabio Luz
Actually indexes and primary keys can be only on primitive types. There's not really a logical reason, the attributes are just ignored. - bubi

1 Answers

1
votes

The key parts of composite keys should be of types that can translate to primitive types in SQL, the type Product cannot be translated to primitive type but ProductId can be translated to int in SQL.
The composite key must be:

public class GoodsIssueProcess
{

    [Key, Column(Order = 1), MaxLength(128)]
    public string DeliveryNote { get; set; }

    [Key, Column(Order = 2)]
    public int ProductId { get; set; }
}