如何插入实体框架中尚不存在的外键?

时间:2013-03-29 17:15:46

标签: asp.net-mvc-4 entity-framework-5

使用.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有用,但我无法找到对它的引用。

2 个答案:

答案 0 :(得分:9)

如果HeaderHeaderData与外键(一对多)关系相关,则应该有一个导航集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>