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
386 views
in Technique[技术] by (71.8m points)

.net - Is is possible to check if an object is already attached to a data context in Entity Framework?

I am getting the following error when trying to attach an object that is already attached to a given context via context.AttachTo(...):

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

Is there a way of achieving something along the lines of:

context.IsAttachedTo(...)

Cheers!

Edit:

The extension method Jason outlined is close, but it doesn't work for my situation.

I am trying to do some work using the method outlined in the answer to another question:

How do I delete one or more rows from my table using Linq to Entities *without* retrieving the rows first?

My code looks a bit like this:

var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();

This works fine, except when I do something else for that user where I use the same method and try to attach a dummy User object. This fails because I have previously attached that dummy user object. How can I check for this?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Here's what I ended up with, which works very nicely:

public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
    where T : IEntityWithKey
{
    ObjectStateEntry entry;
    // Track whether we need to perform an attach
    bool attach = false;
    if (
        context.ObjectStateManager.TryGetObjectStateEntry
            (
                context.CreateEntityKey(entitySetName, entity),
                out entry
            )
        )
    {
        // Re-attach if necessary
        attach = entry.State == EntityState.Detached;
        // Get the discovered entity to the ref
        entity = (T)entry.Entity;
    }
    else
    {
        // Attach for the first time
        attach = true;
    }
    if (attach)
        context.AttachTo(entitySetName, entity);
}

You can call it as follows:

User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);

This works very nicely because it's just like context.AttachTo(...) except you can use the ID trick I cited above each time. You end up with either the object previously attached or your own object being attached. Calling CreateEntityKey on the context makes sure it's nice and generic and will work even with composite keys with no further coding (because EF can already do that for us!).


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

...