当列不是主键时,与E.F. Code First的一对一或一对一关系

时间:2015-09-18 07:10:54

标签: c# entity-framework code-first

我正在开发一个Entity Framework 6.1.3 Code First库,C#和.NET Framework 4.5.1。

我遇到一对一或零关系的问题(或者可能是另一种关系)。

我有两个表,CodesHelperCodes,代码可以有零个或一个帮助程序代码。这是用于创建这两个表及其关系的sql脚本:

CREATE TABLE [dbo].[Code]
(
    [Id] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [SentToRanger] BIT NOT NULL DEFAULT 0, 
    [LastChange] NVARCHAR(50) NOT NULL, 
    [UserName] NVARCHAR(50) NOT NULL, 
    [Source] NVARCHAR(50) NOT NULL, 
    [Reason] NVARCHAR(200) NULL, 
    [HelperCodeId] NVARCHAR(20) NULL,
    CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ),
    CONSTRAINT [FK_Code_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level]),
    CONSTRAINT [FK_Code_HelperCode]
       FOREIGN KEY ([HelperCodeId])
        REFERENCES [dbo].[HelperCode] ([HelperCodeId])
)

CREATE TABLE [dbo].[HelperCode]
(
    [HelperCodeId] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [LastChange] NVARCHAR(50) NOT NULL,
    CONSTRAINT [PK_HelperCode] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ),
    CONSTRAINT [FK_HelperCode_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level])
)

但是,当我尝试对Entity Framework执行相同操作时,它不会这样做。我的问题在于代码和HelperCodes的关键。

这是我的实体框架代码第一个代码:

public class Code
    {
        public string Id { get; set; }
        public byte Level { get; set; }

        // omitted for brevity

        public string HelperCodeId { get; set; }

        public virtual HelperCode HelperCode { get; set; }
    }

class CodeConfiguration : EntityTypeConfiguration<Code>
{
    public CodeConfiguration()
    {
        HasKey(c => c.Id);

        Property(c => c.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        Property(c => c.Id)
            .HasMaxLength(20);

        // omitted for brevity

        Property(c => c.HelperCodeId)
            .HasMaxLength(20)
            .IsOptional();

        HasOptional(c => c.HelperCode)
            .WithRequired(hc => hc.Code);
    }
}

public class HelperCode
{
    public string HelperCodeId { get; set; }
    public byte Level { get; set; }
    public byte CommissioningFlag { get; set; }
    public string LastChange { get; set; }

    public virtual Code Code { get; set; }
}

class HelperCodeConfiguration : EntityTypeConfiguration<HelperCode>
{
    public HelperCodeConfiguration()
    {
        HasKey(h => h.HelperCodeId);

        Property(h => h.HelperCodeId)
            .HasMaxLength(20);

        Property(h => h.Level)
            .IsRequired();

        Property(h => h.CommissioningFlag)
            .IsRequired();

        Property(h => h.LastChange)
            .IsOptional()
            .HasMaxLength(50);
    }
}

此实体代码优先代码使用引用HelperCodes的{​​{1}}在HelperCodes.HelperCodeId表格中生成外键。

如果两个表具有相同的主键,则实体框架仅允许此类关系。

关于如何解决这个E.F.错误的想法?

2 个答案:

答案 0 :(得分:1)

首先:从HelperCodeId类中删除Code

public class Code
{
    public string Id { get; set; }
    public byte Level { get; set; }

    // omitted for brevity

    public virtual HelperCode HelperCode { get; set; }
}

Code配置中:

.HasOptional(i => i.HelperCode)
.WithRequired(i => i.Code);

生成的迁移:

CreateTable(
    "dbo.Codes",
    c => new
        {
            Id = c.String(nullable: false, maxLength: 128),
            Level = c.Byte(nullable: false),
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.HelperCodes",
    c => new
        {
            HelperCodeId = c.String(nullable: false, maxLength: 128),
            Level = c.Byte(nullable: false),
            CommissioningFlag = c.Byte(nullable: false),
            LastChange = c.String(),
        })
    .PrimaryKey(t => t.HelperCodeId)
    .ForeignKey("dbo.Codes", t => t.HelperCodeId)
    .Index(t => t.HelperCodeId);

只有HelperCodes表应该有外键声明。

HelperCodeId是主键,也是外键,因此它确保了0:1的关系。

答案 1 :(得分:0)

关系错误;将代码更改为代码

 public class HelperCode
{

    public byte Level { get; set; }
    public byte CommissioningFlag { get; set; }
    public string LastChange { get; set; }
    public string CodeId { get; set; }
    public virtual Code Code { get; set; }
}

  public class Code
{
    public string Id { get; set; }
    public byte Level { get; set; }
    public virtual HelperCode HelperCode { get; set; }
}

我也从另一方配置关系。

public  class CodeConfiguration : EntityTypeConfiguration<Code>
{
    public CodeConfiguration()
    {
        HasKey(h => h.Id);

        HasOptional(x => x.HelperCode).WithRequired(x => x.Code);
    }
}