[英]One-to-Zero-or-One relationship with E.F. Code First when column is not primary key
I'm developing an Entity Framework 6.1.3 Code First library, C# and .NET Framework 4.5.1. 我正在开发Entity Framework 6.1.3代码优先库,C#和.NET Framework 4.5.1。
I have a problem with a One-to-Zero-or-One relationship (or maybe is another kind of relationship). 我对一对零或一个关系(或者可能是另一种关系)有疑问。
I have two tables, Codes
and HelperCodes
, a code could have zero or one helper code. 我有两个表
Codes
和HelperCodes
,一个代码可以有零个或一个helper代码。 This is the sql script to create these two tables and their relationships: 这是用于创建这两个表及其关系的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])
)
But, when I try to do the same with Entity Framework it doesn't do the same. 但是,当我尝试使用Entity Framework做同样的事情时,它却做不到。 My problem is in Codes and HelperCodes foreing key.
我的问题是在Codes和HelperCodes前键中。
This is my Entity Framework Code First code: 这是我的实体框架代码优先代码:
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);
}
}
This Entity Code First code generates a foreign key in HelperCodes
table using HelperCodes.HelperCodeId
referencing Codes.Id
. 这个实体的Code First代码生成的外键
HelperCodes
使用表HelperCodes.HelperCodeId
引用Codes.Id
。
Entity Framework only allows this kind of relationship if both tables have the same primary key. 如果两个表具有相同的主键,则实体框架仅允许这种关系。
Any idea about how to resolve this EF bug? 关于如何解决此EF错误的任何想法吗?
First: Remove the HelperCodeId
from the Code
class: 首先:从
Code
类中删除HelperCodeId
:
public class Code
{
public string Id { get; set; }
public byte Level { get; set; }
// omitted for brevity
public virtual HelperCode HelperCode { get; set; }
}
In the Code
configuration: 在
Code
配置中:
.HasOptional(i => i.HelperCode)
.WithRequired(i => i.Code);
Generated migration: 产生的迁移:
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);
Only the HelperCodes
table should have the foreign key statement. 只有
HelperCodes
表应该具有外键语句。
HelperCodeId
is a primary key and also a foreign key, so it ensures the 0:1 relationship. HelperCodeId
是一个主键,也是一个外键,因此可以确保0:1的关系。
The relationship is wrong;Change your code to blow code 关系是错误的;将您的代码更改为无效代码
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; }
}
I also configure the relationship from the other side. 我还从另一侧配置关系。
public class CodeConfiguration : EntityTypeConfiguration<Code>
{
public CodeConfiguration()
{
HasKey(h => h.Id);
HasOptional(x => x.HelperCode).WithRequired(x => x.Code);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.