EF Code First 中自引用外键的语法是什么? [英] What is the syntax for self referencing foreign keys in EF Code First?

查看:28
本文介绍了EF Code First 中自引用外键的语法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将外键从 SpouseId 引用到 Contact 表中的 Id.这样做的语法是什么?我似乎无法找到一个例子.谢谢.

I am trying to reference a foreign key from SpouseId to Id in the Contact table. What is the syntax for doing this? I can't seem to find an example. Thanks.

我有一堂这样的课:

public class Contact
{
    public int Id {get;set;}
    public string Name {get;set;}
    public int? SpouseId {get;set;}
}

EDIT1根据链接 由 Joel Cunningham 提供,Morteza 的回答我添加了一些额外的代码.

EDIT1 Per the link provided by Joel Cunningham and the answer from Morteza I have added some additional code.

ContactMap.cs

ContactMap.cs

public partial class ContactMap : EntityTypeConfiguration<Contact>
{
  public ContactMap()
     {
       this.ToTable("Contact");
       this.HasKey(c => c.Id);
       this.HasOptional(c => c.Spouse)
           .WithMany()
           .IsIndependent()
           .Map(m => m.MapKey(fk => fk.Id, "SpouseId"));
     }
}

MyObjectContext.cs

MyObjectContext.cs

public class MyObjectContext : DbContext, IDbContext
{
  public DbSet<Contact> Contacts {get;set;}
  protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Configurations.Add(new ContactMap());
     }
}

注意:我还在我的 Contact 类中向我的 Spouse 属性添加了[ForeignKey("SpouseId")]"属性.不幸的是,我不断收到序列包含多个匹配元素".

Note: I also added the "[ForeignKey("SpouseId")]" attribute to my Spouse property in my Contact class. Unfortunately I keep getting "Sequence contains more than one matching element".

Morteza 在下面的回答是正确的.总结:对于自引用外键,您可以将属性标记为[ForeginKey("SpouseId")] 或使用下面的 fluent API 示例.我在一些评论中报告的错误是由我的单元测试引起的.EF以正确的方式生成了数据库.我找到了一个很好的 link 其中 Craig Stuntz 概述了为什么自动递增键和自引用外键会导致无法确定相关操作的有效顺序" 错误.我相信这就是我的问题所在.希望这对某人有所帮助.

Morteza's answers below is correct. To summarize: For self referencing foreign keys you can either mark the property as a "[ForeginKey("SpouseId")] OR use the fluent API example below. The errors I reported in some of my comments were caused by my unit test. EF generated the db the correct way. I found a good link where Craig Stuntz outlined why auto-increment keys and self-referencing foreign keys can cause the "Unable to determine a valid ordering for dependent operations" error. I believe this is what my problem is. Hope this helps someone.

推荐答案

这样的事情会起作用:

public class Contact
{
    public int Id {get;set;}
    public string Name {get;set;}
    public int? SpouseId {get;set;}

    [ForeignKey("SpouseId")]
    public Contact Spouse {get;set;}
}

ForeignKeyAttribute 已通过 CTP5 程序集添加到 System.ComponentModel.DataAnnotations.

ForeignKeyAttribute has been added to System.ComponentModel.DataAnnotations by CTP5 assembly.

由于 CTP5 中的错误,创建一个独立的自引用关联会引发异常.解决方法是改用外键关联(无论如何始终推荐使用).

Due to a bug in CTP5, creating an Independent Self Referencing Associations throws an exception. The workaround is to use Foreign Key Associations instead (which is always recommended regardless).

如果您愿意,也可以使用 fluent API 来实现此目的:

You can also use fluent API to achieve this, if you prefer:

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? SpouseId { get; set; }                

    public Contact Spouse { get; set; }
}

public class Ctp5Context : DbContext
{
    public DbSet<Contact> Contacts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Contact>()
                    .HasOptional(c => c.Spouse)
                    .WithMany()
                    .HasForeignKey(c => c.SpouseId);
    }
}

使用模型:

using (var context = new Ctp5Context())
{
    Contact contact = new Contact()
    {
        Name = "Morteza",
        Spouse = new Contact()
        {
            Name = "Code-First"
        }
    };
    context.Contacts.Add(contact);
    context.SaveChanges();
}

这篇关于EF Code First 中自引用外键的语法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆