Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert with foreign key that doesn't exist yet in Entity Framework?

Using .NET 4, MVC 4, Entity Framework 5, SQL Server;

I want to insert in one transaction a new Header record and several new HeaderData records which all have a Foreign Key to the inserted Header record. Header record has an Identity int Primary Key.

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? 

So problem is, I don't know what the header record ID is going to be to put in the data records' FK field until after it is committed. Or do I? Just referencing h.ID before the SaveChanges/Commit did not work, it returned 0.

Options: 1) Should I just commit the header record first, get the PK to use, then populate the data record models and commit them separately? Might have to do a rollback of the header in such case, sounds like a less than optimal way to go about it.

2) Should I be using a GUID PK or similar instead, where I create it here in the app? That is the only place the records can be added from anyway.

3) Is there a slick way in Entity Framework (temporary EntityKey maybe?), and have it do the transaction inserts so that it will automatically put the right header ID in the data records' FK fields? This seems doable to EF but I couldn't exactly find a reference to it.

like image 275
Sswan Avatar asked Mar 29 '13 17:03

Sswan


People also ask

How do I add a foreign key to EF core?

The [ForeignKey(name)] attribute can be applied in three ways: [ForeignKey(NavigationPropertyName)] on the foreign key scalar property in the dependent entity. [ForeignKey(ForeignKeyPropertyName)] on the related reference navigation property in the dependent entity.

What happens when a foreign key is deleted?

When a referenced foreign key is deleted or updated, respectively, the columns of all rows referencing that key will be set to NULL . The column must allow NULL or this update will fail.

How do I add a foreign key in EDMX?

According to Relationships/Associations with the EF Designer, the steps to create a foreign key association are: Right-click an empty area of the design surface, point to Add New, and select Association…. Fill in the settings for the association in the Add Association dialog.

Is it possible for an entity to not have a primary key?

Every entity in the data model shall have a primary key whose values uniquely identify entity instances. The primary key attribute cannot be optional (i.e., have null values).


1 Answers

If Header and HeaderData are related by a foreign key (one-to-many) relationship you should have a navigation collection Header.HeaderDatas (of type ICollection<HeaderData> or another collection type) in Header or a navigation reference HeaderData.Header (of type Header) in HeaderData or even both.

In either case the better way is to build the relationship using those navigation properties:

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();

Or:

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();

You don't need to set the FK directly. EF will correctly "translate" the navigation properties you've set into the necessary foreign key values for the database tables.

like image 186
Slauma Avatar answered Nov 10 '22 21:11

Slauma