开发者

Entity Framework 4.1 Code First, One-to-One with one table joining to a single key field of of composite key

开发者 https://www.devze.com 2023-03-22 10:28 出处:网络
I\'m just beginning with EF4.1 Code First, and开发者_Python百科 I pretty like it. Here\'s the story :

I'm just beginning with EF4.1 Code First, and开发者_Python百科 I pretty like it.

Here's the story : A Codif class is composed of a key from a Domaine class, an Entite class, and Reference class, and a fourth field which is some text. Reference and Codif have an one-to-one relationship.

Thing is, when it creates the Database, it creates some ugly fields in my Reference entity, creating duplicate fields of the Codif Entity. Good point : When I manipulate my Reference object however, I have the expected behaviour of accessing the Codif property, and the duplicate fields are invisible.

Here's the code :

public class Reference
{
    public int ReferenceId { get; set; }
    public string Libelle { get; set; }
    public virtual Codif Codif { get; set; }

}

public class Domaine
{
    public int DomaineId { get; set; }
    public string Libelle { get; set; }

}

public class Codif
{
    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int DomaineId { get; set; }
    [InverseProperty("DomaineId")]
    public virtual Domaine Domaine { get; set; }

    [Key, Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int EntiteId { get; set; }
    [InverseProperty("EntiteId")]
    public virtual Entite Entite { get; set; }

    [Key, Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ReferenceId { get; set; }
    [InverseProperty("ReferenceId")]
    public virtual Reference Reference { get; set; }

    [Key, Column(Order = 3)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Codification { get; set; }
}

public class Entite
{
    public int EntiteId { get; set; }
    public string Nom { get; set; }
    public string Email { get; set; }
}

And here's the result in the tables (images) :

Codif

Reference

  1. In the Reference class, how can I specify that ReferenceId is the foreign key to be used against a SINGLE field of Codif ?
  2. How to get rid of those duplicate fields in Reference ?
  3. How to remove the Reference_ReferenceId in Codif table while preserving the navigation property ?

Thank you for your support.

Marc

Edit : I'm working with an SQL Compact Edition 4 database


Replace all your [InverseProperty("xxx")] attributes by [ForeignKey("xxx")]. I think that this is what you actually want. [InverseProperty] refers to the navigation property on the other side of the relationship which can never be a scalar property.

Edit

You could in addition to the FK attribute set the [InverseProperty] attribute on the Reference property in your Codif class:

public class Codif
{
//...

    [Key, Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ReferenceId { get; set; }
    [ForeignKey("ReferenceId")]
    [InverseProperty("Codif")] // <-- refers to Codif property in Reference class
    public virtual Reference Reference { get; set; }

//...
}

But it think it's not really necessary because EF should detect the correct relationship between Reference and Codif by convention. (I'm not sure though for one-to-one relationships.)

Edit

Problems!

First: As far as I can see you must specify the one-to-one relationship in Fluent API because EF cannot determine otherwise what's the principal and what's the dependent:

modelBuilder.Entity<Reference>()
            .HasOptional(c => c.Codif)
            .WithRequired(c => c.Reference);

Second: EF will still complain because of the composed key or because ReferenceId is not the key alone. If ReferenceId were the only key in Codif it would work.

Edit

I'm trying to understand what you want to achieve. Apparently your composed key in Codif is supposed to ensure that any combination of the four field values can exist only once. But this conflicts with the one-to-one relationship imo, for example this would be valid table entries:

Table Codif:
DomaineId    EntiteId    ReferenceId    Codification
----------------------------------------------------
1            1           1              "A"
2            1           1              "A"
1            2           1              "A"
1            1           2              "A"
1            1           1              "B"
etc...

But as you can see: You can have multiple rows with the same ReferenceId which means that you cannot have a one-to-one relationship to Reference. Here you have 4 Codif entities which refer to the same Reference entity with Id = 1.

Now, I guess, the fact that you want to have a one-to-one relationship means that there is an additional constraint so that ReferenceId in Codif table can occur only once. In other words: The rows 2, 3 and 5 in the example above are invalid from business viewpoint (although valid from DB viewpoint).

If this is the case I would actually make ReferenceId the single key in Codif and make sure from business logic that the other combinations of values in the DB are unique (Query if exists before you insert a new Codif). On database side you could create a unique index over the other three fields to ensure that the combinations are always unique in the database. EF cannot check this internally though since unique constraints are not yet supported.

0

精彩评论

暂无评论...
验证码 换一张
取 消