实体框架代码先fluent api

Posted

技术标签:

【中文标题】实体框架代码先fluent api【英文标题】:entity framework code first fluent api 【发布时间】:2016-04-09 13:40:51 【问题描述】:

我是第一次使用 fluent api。我能够使用一对多和多对多关系建立关系。

但我有一个使用一对一关系的澄清。

我有两个表 tableA 和 tableB 其中 tableA 有两个字段

public class tableA

 public int tAId get;set;
 public string desc get;set;
 public tableB tableB get;set;

tableB 有以下字段:

public class tableB

  public int tBId get;set;
  public int refKeyfromTableAget;set;
  public string somedescget;set;
  public tableA tableA get;set;


我在一个单独的类中定义约束,例如:

public class tableAConfig:BaseEntity<tableA>

public tableAConfig()

  HasKey(p=>p.tAId);
Property(p=>p.tAId).IsRequired();

//This line has syntatical error
HasForeignKey(p=>p.tAId);


如何在代码优先的方法中定义上述类中的外键关系?

【问题讨论】:

【参考方案1】:

如下定义你的 fluent api 配置类:

public class tableAConfig:BaseEntity<tableA>

    public tableAConfig()
    
        HasKey(p=>p.tAId);

        HasOptional(p => p.tableB )
            .WithRequired( p => p.tableA );
    

考虑到tableB实体上的属性refKeyfromTableA是无用的,因为数据库中的一对一关系是在主键之间形成的。因此,在您的情况下,如果它们的 tAId 和 tBId 列具有相同的值,则 2 个实体是相关的。因此,数据库无法生成至少一个实体的主键值。例如在 tableB 的配置中,你可以这样做:

Property(e => e.tBId)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

除了 WithRequired 方法,你还可以使用 WithOptionalDependent 和 WithOptionalPrincipal 方法来形成你想要的一对一关系。

【讨论】:

【参考方案2】:

我还没有对 fluent API 进行 1:1 的操作,但我已经使用属性完成了。我修复了一个代码示例,演示了与您的示例保持一致的属性方法,也许它会对您有所帮助:

public class tableA

    public int Id  get; set; 

    public string desc  get; set; 

    public tableB tableB  get; set; 


public class tableB

    // In one-to-one relationship, one end must be principal and second end must be dependent. 
    // tableA is the one which will be inserted first and which can exist without the dependent one. 
    // tableB end is the one which must be inserted after the principal because it has foreign key to the principal.

    [Key, ForeignKey("tableA")]
    public int Id  get; set; 

    // 'Required' attribute because tableA must be present
    // in order for a tableB to exist
    [Required]
    public virtual tableA tableA  get; set; 

    public string somedesc  get; set; 

【讨论】:

以上是关于实体框架代码先fluent api的主要内容,如果未能解决你的问题,请参考以下文章

EF 6.X 中的实体框架代码优先 Fluent API 默认值

EFEF框架 Code First Fluent API

实体框架Fluent API中的两个FK

实体框架(CTP5、Fluent API)。重命名导航属性的列

使用实体框架 Fluent Api 映射 System.Uri

我是不是需要使用 Fluent API 配置与实体框架的关系的双方?