Creating Many-2-Many reference with EF

2019-08-29 11:23发布

问题:

In my current project (which is really small) i have 3 tables/POCO entities which i would like to manipulate using EF.

The Tables are:

  1. Status (contains status details)
  2. StatusStatusType (which is needed because of the many-2-many relationship)
  3. StatusType (A table which is used to group statuses by type)

I now want to create a new Status in the database and user code like you see below

//Create new status (POCO) entity
var newStatus = new Status {
    StatusId = status.Id,
    UserId = user.Id,
    Text = status.text,
    CreateDate = DateTime.Now
};

// Persist need status to database
using (var db = new demoEntities())
{
    db.Statuses.AddObject(newStatus);
    db.SaveChanges();
}

This code works fine but i want to also set StatusType of the status entity. All possible status types are already included in the StatusType table. I don't want to create new statuses only create a reference.

I figured i should use something like :

status.StatusTypes == "new";

Update 22-04-2012 13:31

The example is simplified and spans multiple projects within a solution. Because of this i prefer not to use code within the create section (e.g. demoEntities).I do however know the PK of the status i need to reference.

回答1:

If you know that your status type already exists you also must now its primary key. Once you have a primary key value you can use this approach:

var newStatus = new Status {
    StatusId = status.Id,
    UserId = user.Id,
    Text = status.text,
    CreateDate = DateTime.Now
};

// Just dummy object for existing status type
var existingStatusType = new StatusType {
    Id = existingStatusTypeId
};

// Persist need status to database
using (var db = new demoEntities())
{
    db.Statuses.AddObject(newStatus);
    // First let EF know that the status type already exists
    // Attaching prior to making relation is important!
    db.StatusTypes.Attach(existingStatusType);
    // Now make relation between new and existing entity 
    newStatus.StatusTypes.Add(existingStatusType);
    db.SaveChanges();
}

If you don't want to create relation inside of the persistence code you must use little bit different approach.

var newStatus = new Status {
    StatusId = status.Id,
    UserId = user.Id,
    Text = status.text,
    CreateDate = DateTime.Now
};

// Just dummy object for existing status type
var existingStatusType = new StatusType {
    Id = existingStatusTypeId
};

newStatus.StatusTypes.Add(existingStatusType);

// Persist need status to database
using (var db = new demoEntities())
{
    // This will add both newStatus and existingStatusType as new entities
    db.Statuses.AddObject(newStatus);
    // You must fix it to make sure that existingStatusType is not inserted 
    // to database again
    status.StatusTypes.ForEach(st =>
        db.ObjectStateManager.ChangeObjectState(st, EntityState.Unchanged));
    db.SaveChanges();
}