简体   繁体   中英

How I can achieve two different foreign keys in Entity Framework?

I need to bind some relations in Entity Framework Code First but I don't know how to. I searched deeply, I tried a lot of ways but still without luck. I think I need to use the fluent API.

Scenario

Organizations has many Notes . Projects has many Notes . Notes has one Organization or Project .

The idea is to bind every entity ( Organization or Project ) to only one column in Note entity: SourceKey .

Organization

public class Organization
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    [Required(ErrorMessage = "A name is required.")]
    public string Name { get; set; }

    public virtual ICollection<Project> Projects { get; set; }
    public virtual ICollection<Note> Notes { get; set; }
}

Project

public class Project
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    [Required(ErrorMessage = "An organization is required.")]
    [Display(Name = "Organization")]
    public Guid OrganizationID { get; set; }

    [Required(ErrorMessage = "A name is required.")]
    public string Name { get; set; }

    public virtual Organization Organization { get; set; }
    public virtual ICollection<Note> Notes { get; set; }
}

Note

public class Note
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    public Guid SourceKey { get; set; }

    [Required(ErrorMessage = "A title is required.")]
    public string Title { get; set; }

    [Column(TypeName = "ntext")]
    public string Value { get; set; }

    public string Tags { get; set; }
}

So an example of data can be:

Organizations

7846ac27-d490-4483-8f0b-975a11333dea, Google

Projects

3446ac27-d490-4323-8121-921a11333dac, Search
7846ac27-8497-5683-213b-933a11233abc, Maps

Notes

1236ac27-d490-4323-8121-921a11333dac, 7846ac27-d490-4483-8f0b-975a11333dea, A note for Google organization
2346ac27-d490-4323-8121-921a11335aab, 7846ac27-d490-4483-8f0b-975a11333dea, Another note for Google organization
3456ac27-d490-4323-8121-921a11331bcc, 7846ac27-8497-5683-213b-933a11233abc, Just a note for Maps project

BTW

I don't need to navigate from Notes (up) to Organization or Project. If I have an Organization or Project, I will need to navigate (down) to Notes.

As mentioned above, if you don't require navigation properties from notes, you can omit them.

If you then included two fields on the Note class to use for foreign key associations:

public class Note
{
    // Code

    public Guid OrganizationId { get; set; }
    public Guid ProjectId { get; set; }
}

I assume most notes won't belong to both an Organisation , and a Project (although they can).

You should be able to configure your mapping using the fluent API like this:

modelBuilder.Entity<Organization>()
        .HasMany(o => o.Notes)                    // Many Notes
        .WithOptional()                           // No navigation property on Notes            
        .HasForeignKey(n => n.OrganizationId );   // Use OrganizationId as a foreign key

modelBuilder.Entity<Project>()
        .HasMany(o => o.Notes)
        .WithOptional()
        .HasForeignKey(n => n.ProjectId);

You can define the Note entity without navigation properties,

public class Note
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    public Guid SourceKey { get; set; }

    [Required(ErrorMessage = "A title is required.")]
    public string Title { get; set; }

    [Column(TypeName = "ntext")]
    public string Value { get; set; }

    public string Tags { get; set; }

    public int OrganizationId { get; set; }
    public int ProjectId { get; set; }
}

If you don't need navigation properties, you can define it simply using the class below:

public class Note
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid NoteID { get; set; }

    public Guid SourceKey { get; set; }

    [Required(ErrorMessage = "A title is required.")]
    public string Title { get; set; }

    [Column(TypeName = "ntext")]
    public string Value { get; set; }

    public string Tags { get; set; }

    public Guid OrganizationId { get; set; }
    public Guid ProjectId { get; set; }

}

Note OrganizationId and ProjectId are of type Guid .

I think that the use of one column (SourceKey) for multiple foreign keys is not possible. It throws you an error. I was pretty sure that was possible but maybe I'm confused with the MyISAM tables in MySQL. I will use the foreign keys columns in the Note model as Chris suggest. Thanks to everybody.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM