C# 实体框架4-如何使用Joiner表C插入记录#
我一直在编写一个非常大的项目,但在EF4和joiner表操作方面遇到了麻烦 假设我们有以下SQL表定义:C# 实体框架4-如何使用Joiner表C插入记录#,c#,entity-framework,c#-4.0,entity-framework-4,linq-to-entities,C#,Entity Framework,C# 4.0,Entity Framework 4,Linq To Entities,我一直在编写一个非常大的项目,但在EF4和joiner表操作方面遇到了麻烦 假设我们有以下SQL表定义: CREATE TABLE [dbo].[SQLEntity]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Field1] [nvarchar](128) NOT NULL, [Field2] [nvarchar] (256), [DateAdded] [datetime] NOT NULL, CONSTRAINT [
CREATE TABLE [dbo].[SQLEntity](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Field1] [nvarchar](128) NOT NULL,
[Field2] [nvarchar] (256),
[DateAdded] [datetime] NOT NULL,
CONSTRAINT [PK_SQLEntity] PRIMARY KEY CLUSTERED (
[Id] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Util_LookupValues](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Description] [nvarchar](64) NOT NULL,
CONSTRAINT [PK_Util_LookupValues] PRIMARY KEY CLUSTERED (
[Id] ASC
)WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Xref_EntityValues](
[SQLEntityId] [bigint] NOT NULL,
[LookupId] [int] NOT NULL,
CONSTRAINT [PK_Xref_PositionBenefits] PRIMARY KEY CLUSTERED (
[SQLEntityId] ASC,
[LookupId] ASC
)WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Xref_EntityValues] WITH CHECK ADD CONSTRAINT [FK_Xref_EntityValues_Entity] FOREIGN KEY([SQLEntityId])
REFERENCES [dbo].[SQLEntity] ([Id])
GO
ALTER TABLE [dbo].[Xref_EntityValues] CHECK CONSTRAINT [FK_Xref_EntityValues_Entity]
GO
ALTER TABLE [dbo].[Xref_EntityValues] WITH CHECK ADD CONSTRAINT [FK_Xref_EntityValues_Util_LookupValues] FOREIGN KEY([LookupId])
REFERENCES [dbo].[Util_LookupValues] ([Id])
GO
ALTER TABLE [dbo].[Xref_EntityValues] CHECK CONSTRAINT [FK_Xref_EntityValues_Util_LookupValues]
GO
基于这些表对域模型进行装箱后,您将得到两个实体:
SqlEntity和Util_lookupvalue
此时,Util_LookupValues是一个表,其值仅为查找而定义!Xref_EntityValues是一个联接表,它将实体对象与查找值绑定在一起,使我们可以在两者之间建立meny到meny的关系,从而保留查找表的“查找”功能
Util_LookupValues内容
Id Description
--- ------------
1 Person
2 Car
如果未向域模型添加任何更改(在本问题中,将其称为DataEntities),则将SQLEntity与PK为1和2的Util_LookupValues对象绑定,操作如下:
IEnumerable<Util_LookupValues> lookupValues = DataEntities.Util_LookupValues.Where( lv => lv.Id == 1 || lv.Id == 2);
SQLEntity entity = new SQLEntity();
entity.Field1 = "some field";
entity.Field2 = "another field";
entity.DateAdded = DateTime.Now;
foreach(Util_LookupValues val in lookupValues)
{
entity.Util_LookupValues.Add(val);
}
DataEntities.SQLEntities.Add(entity);
DataEntities.SaveChanges();
SQL Entity:
Id Field1 Field2 DateAdded
-- ------- ------ ----------
1 some field another field 04/04/2012
Xref_EntityValues:
SQLEntityId LookupId
----------- ---------
1 3
1 4
and Util_LookupValues:
Id Description
--- ------------
1 Person
2 Car
3 Person
4 Car
如何使Util_LookupValues只包含2条原始记录,而Xref_EntityValues包含正确的外键
Xref_EntityValues:
SQLEntityId LookupId
----------- ---------
1 1
1 2
Util_LookupValues:
Id Description
--- ------------
1 Person
2 Car
这条线
IEnumerable<Util_LookupValues> lookupValues = DataEntities.Util_LookupValues
.Where( lv => lv.Id == 1 || lv.Id == 2);
DataEntities.SQLEntities.Add(entity);
。。。是否使用相同的DataEntities
上下文实例?您的代码片段表明了这一点,但可能是“伪代码”
如果实例不同,则会得到实体的重复,是的
因此,您有三种选择:
- 确保上下文实例相同
- 将返回的
附加到第二个上下文:Util\u LookupValues
foreach(Util_LookupValues val in lookupValues) { DataEntities.Util_LookupValues.Attach(val); entity.Util_LookupValues.Add(val); }
- 根本不执行第一个查询。而是创建“存根”实体并附加它们:
这是因为在将对象附加到上下文以建立新关系时,EF只需要知道主键属性值var val = new Util_LookupValues { Id = 1 }; DataEntities.Util_LookupValues.Attach(val); entity.Util_LookupValues.Add(val); val = new Util_LookupValues { Id = 2 }; DataEntities.Util_LookupValues.Attach(val); entity.Util_LookupValues.Add(val);