Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

c# - Entity Framework Creating new data rows during db.SaveChanges()

Creating an AngularJS application based off of this tutorial: http://jphoward.wordpress.com/2013/01/04/end-to-end-web-app-in-under-an-hour/

Classes:

public class Todo
{
    public int ID { get; set; }
    public virtual Status Status { get; set; }
}

public class Status
{
    public int ID { get; set; }
    public string Type { get; set; }
}

Functionality is that you click a button and it changes the status. When the button is clicked, all the right things are being passed in to Visual Studio. Originally it wasn't updating at all. After some research I found some ways to force the changes, but then at db.SaveChanges() it adds a new row to Status that has the same 'Type', just an incremented ID from whatever the last one is at.

JS that calls update:

Api.Todo.update({ id: todoID }, todo, function () {
    $location.path('/');
});

Which hits VS on this function:

private DataContext db = new DataContext();

// PUT api/Todo/5
HttpResponseMessage PutTodo(int id, Todo todo)
{
    if (!ModelState.IsValid)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }

    if (id != todo.ID)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

    // Found a stack overflow that mentioned that you need to check for things already being tracked
    var entry = db.Entry(todo);

    if (entry.State == EntityState.Detached)
    {
        var set = db.Set<Todo>();
        Todo attachedEntity = set.Find(todo.ID);  // You need to have access to key
        if (attachedEntity != null)
        {
            // The following code does not update any changes to the foreign keys
            var attachedEntry = db.Entry(attachedEntity);
            attachedEntry.CurrentValues.SetValues(todo);
            db.Entry(attachedEntity).State = EntityState.Modified;

            // When this didn't work, I tried just changing the status on the already attached entity
            //attachedEntity.Status = todo.Status;
            //db.SaveChanges();
            // However when it hit SaveChanges() it created a new row in the Status table.
        }
        else
        {
            //This code was never hit
            entry.State = EntityState.Modified; // This should attach entity
        }
    }

    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }

I'm nearing the end of my capabilities and would love a little help or direction.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
public class Todo
{
    public int ID { get; set; }

    //Foreign key
    public int StatusID { get; set; } //<====Add this line

    public virtual Status Status { get; set; }
}

When you post your data update the foreign key property,not the navigational property

Also ,check this: Why Does Entity Framework Reinsert Existing Objects into My Database? http://msdn.microsoft.com/en-us/magazine/dn166926.aspx


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...