使用.NET 4,MVC 4,Entity Framework 5,SQL Server;
我想在一个事务中插入一个新的Header记录和几个新的HeaderData记录,这些记录都有一个外键到插入的Header记录。标题记录具有Identity int主键。
Entities.Header h = new Entities.Header();
h.Name = name;
h.Time = DateTime.Now;
h.Comments = comments;
db.Headers.Add(h);
// db.SaveChanges(); // Save changes here?
// and get ID to use below via h.ID?
foreach (DataRecord dr in datarecords) // my own custom types here
{
Entities.HeaderData hd = new Entities.HeaderData();
// hd.header = thisid // ?? this is the FK to Header.ID, its Identity int PK
hd.name = dr.name
hd.value = dr.value
db.HeaderDatas.Add(hd)
}
db.SaveChanges(); // or wait to save all here?
问题是,我不知道将头记录ID放入数据记录的FK字段之前,直到它被提交为止。或者我呢?只是在SaveChanges / Commit不起作用之前引用h.ID,它返回0。
选项: 1)我应该先提交头记录,使用PK,然后填充数据记录模型并单独提交吗?在这种情况下,可能不得不对标题进行回滚,这听起来不是最佳方式。
2)我应该使用GUID PK还是类似的,我在应用程序中创建它?这是唯一可以添加记录的地方。
3)实体框架中是否有一个灵巧的方式(临时的EntityKey可能?),并让它进行事务插入,以便它自动将正确的标头ID放入数据记录的FK字段中?这似乎对EF有用,但我无法找到对它的引用。
答案 0 :(得分:9)
如果Header
和HeaderData
与外键(一对多)关系相关,则应该有一个导航集Header.HeaderDatas
(类型为ICollection<HeaderData>
或其他) Header
中的集合类型)或HeaderData.Header
中的导航参考Header
(类型HeaderData
),甚至两者都有。
在任何一种情况下,更好的方法是使用这些导航属性建立关系:
Entities.Header h = new Entities.Header();
h.HeaderDatas = new List<HeaderData>();
// ...
foreach (DataRecord dr in datarecords)
{
Entities.HeaderData hd = new Entities.HeaderData();
//...
h.HeaderDatas.Add(hd)
}
db.Headers.Add(h);
db.SaveChanges();
或者:
Entities.Header h = new Entities.Header();
// ...
foreach (DataRecord dr in datarecords)
{
Entities.HeaderData hd = new Entities.HeaderData();
//...
hd.Header = h;
db.HeaderDatas.Add(hd);
}
db.SaveChanges();
您无需直接设置FK。 EF将正确“转换”您设置的导航属性到数据库表的必要外键值。
答案 1 :(得分:0)
不需要导航属性。使用事务并调用SaveChanges()两次;添加第一个实体后一次,最后一次。 由于EF可以使用多种不同的方式,下面的示例可能不是您的具体情况的确切解决方案,但它应该推动归宿。
<dependencies>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-tooling-api</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-base-services</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-base-services-groovy</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.10</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>repo.gradle.org</id>
<url>https://repo.gradle.org/gradle/libs-releases-local/</url>
</repository>
</repositories>