我有2个标准实体:
组:
[Table("CONTROL_GROUP", Schema = "CONTROL")]
public partial class Group
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
[Column("ID")]
public decimal Id { get; set; }
[Required]
[Column("NAME")]
[MaxLength(200)]
public string Name { get; set; }
public virtual GroupMetier GroupMetier { get; set; }
}
GroupMetier:
[Table("CONTROL_GROUP_METIER", Schema = "CONTROL")]
public partial class GroupMetier
{
[Key]
[Required]
[Column("GROUP_ID")]
public int GroupId { get; set; }
[Required]
[Column("NAME")]
[MaxLength(200)]
public string Name { get; set; }
public virtual Group Group { get; set; }
}
在我的模型构建器中,我将关系定义如下:
// GroupMetier 0..1 <-> 1 Group
modelBuilder.Entity<GroupMetier>()
.HasRequired<Group>(gm => gm.Group)
.WithOptional(g => g.GroupMetier)
但是,在执行时,当我尝试使用此linq来检索组时:
_context.Groups.Where(item => item.GroupMetier != null)
生成的sql无法执行:
SELECT
"Extent3"."GROUP_ID" AS "GROUP_ID",
"Extent1"."ID" AS "ID",
"Extent1"."NAME" AS "NAME",
"Extent2"."GROUP_ID" AS "GROUP_ID1"
FROM "CONTROL"."CONTROL_GROUP" "Extent1"
LEFT OUTER JOIN "CONTROL"."CONTROL_GROUP_METIER" "Extent2" ON "Extent1"."ID" = "Extent2"."GroupId"
INNER JOIN "CONTROL"."CONTROL_GROUP_METIER" "Extent3" ON "Extent1"."ID" = "Extent3"."GroupId"
WHERE (1 = 1)
问题显然来自于尝试加入非现有"Extent2"."GroupId"
列而非右"Extent2"."GROUP_ID"
我是否未能在某个地方宣布这种关系起作用?
编辑:根据要求,CONTROL.CONTROL_GROUP_METIER表:
CREATE TABLE CONTROL.CONTROL_GROUP_METIER
(
GROUP_ID INTEGER NOT NULL,
NAME VARCHAR2(200 CHAR) NOT NULL
)
TABLESPACE CONTROL_DATA
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX CONTROL.CONTROL_GROUP_METIER_PK ON CONTROL.CONTROL_GROUP_METIER
(GROUP_ID)
LOGGING
TABLESPACE CONTROL_DATA
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE CONTROL.CONTROL_GROUP_METIER ADD (
CONSTRAINT CONTROL_GROUP_METIER_PK
PRIMARY KEY
(GROUP_ID)
USING INDEX CONTROL.CONTROL_GROUP_METIER_PK
ENABLE VALIDATE);
ALTER TABLE CONTROL.CONTROL_GROUP_METIER ADD (
CONSTRAINT CONTROL_GROUP_METIER_R01
FOREIGN KEY (GROUP_ID)
REFERENCES CONTROL.CONTROL_GROUP (ID)
ENABLE VALIDATE);
答案 0 :(得分:2)
我是否未能在某个地方宣布这种关系起作用?
您的配置适用于所谓的Shared Primary Key Association,通常会产生这样的迁移(只是为了测试映射):
CreateTable(
"CONTROL.CONTROL_GROUP_METIER",
c => new
{
GROUP_ID = c.Int(nullable: false),
NAME = c.String(nullable: false, maxLength: 200),
})
.PrimaryKey(t => t.GROUP_ID)
.ForeignKey("CONTROL.CONTROL_GROUP", t => t.GROUP_ID)
.Index(t => t.GROUP_ID);
然而,它实际上产生了这个:
CreateTable(
"CONTROL.CONTROL_GROUP_METIER",
c => new
{
GROUP_ID = c.Int(nullable: false, identity: true),
NAME = c.String(nullable: false, maxLength: 200),
Group_Id = c.Decimal(nullable: false, precision: 18, scale: 2),
})
.PrimaryKey(t => t.GROUP_ID)
.ForeignKey("CONTROL.CONTROL_GROUP", t => t.Group_Id)
.Index(t => t.Group_Id);
你可以看到的并不是你想要的。
为什么?为了更好地理解,请将显式ForeignKey
属性应用于Group
属性:
[ForeignKey("GroupId")]
public virtual Group Group { get; set; }
现在迁移失败并出现以下错误:
GroupMetier_Group_Target_GroupMetier_Group_Source ::参照约束的从属角色中的所有属性的类型必须与“主体角色”中的相应属性类型相同。财产的类型&#39; GroupId&#39;实体&#39; GroupMetier&#39;不符合财产的类型&#39; Id&#39;实体&#39; Group&#39;在参考约束&#39; GroupMetier_Group&#39;。
所以问题是Group.Id
属性类型是decimal
而GroupMetier.GroupId
属性类型是int
,在这种情况下,EF无法识别关系并尝试使用One-to-One Foreign Key Association这当然与您的数据库模型不匹配。
如何解决?这很难说,但你不知何故应该同时制作int
或decimal
两个属性。
答案 1 :(得分:1)
您是否尝试过ForeignKey注释?
[ForeignKey("GROUP_ID")]
public virtual Group Group { get; set; }
答案 2 :(得分:0)
在流畅的API中
modelBuilder.Entity<GroupMetier>()
.HasRequired<Group>(gm => gm.Group)
.WithOptional(g => g.GroupMetier)
.Map(g => g.MapKey("GROUP_ID"));