.net - 是否可以检查对象是否已附加到 Entity Framework 中的数据上下文?

标签 .net entity-framework

尝试通过 context.AttachTo(...) 附加已附加到给定上下文的对象时,出现以下错误:

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

有没有一种方法可以实现以下目标:

context.IsAttachedTo(...)

干杯!

编辑:

Jason 概述的扩展方法很接近,但它不适用于我的情况。

我正在尝试使用另一个问题的答案中概述的方法做一些工作:

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

我的代码看起来有点像这样:

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

这工作正常,除非我使用相同的方法为该用户执行其他操作并尝试附加虚拟 User 对象。这失败了,因为我之前已经附加了该虚拟用户对象。我如何检查这一点?

最佳答案

这是我最终得到的结果,效果非常好:

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

您可以按如下方式调用它:

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

这非常有效,因为它就像 context.AttachTo(...) 一样,只不过您每次都可以使用我上面引用的 ID 技巧。您最终会得到之前附加的对象或附加的您自己的对象。在上下文中调用 CreateEntityKey 可确保它良好且通用,并且即使使用复合键也无需进一步编码(因为 EF 已经可以为我们做到这一点!)。

编辑,十二年后(2021 年 12 月)...噢!

这是我在 EF Core 中使用的内容:

public static class EfExtensions
{
    public static T AttachToOrGet<T>(this DbContext context, Func<T,bool> predicate, Func<T> factory)
        where T : class, new()
    {
        var match = context.Set<T>().Local.FirstOrDefault(predicate);
        if (match == null)
        {
            match = factory();
            context.Attach(match);
        }

        return match;
    }
}

用法:

var item = db.AttachToOrGet(_ => _.Id == someId, () => new MyItem { Id = someId });

您可以重构它以使用实体 key ,但这足以让任何人开始!

关于.net - 是否可以检查对象是否已附加到 Entity Framework 中的数据上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1715501/

相关文章:

.net - 查询更新多行

c# - 在 WebAPI 中使用 Entity Framework 对表进行 GET 调用时出现异常

c# - Entity Framework 的通用存储库方法出错

.net - 使用 Entity Framework 4 的领域驱动设计

c# - 在 C# 文件中设置 TFS 版本号

C# 编译器 - 未分配字段和局部变量初始值

c# - 获取图表上 LinearAxis 的自动间隔值 (System.Windows.Controls.DataVisualization.Charting)

c# - 如何从 Visual Studio 2017 中的 .NET Framework 4.5 控制台应用程序引用 .NET 标准库?

mysql - 在 MySql 数据库的 Entity Framework 中运行更新数据库时表 'xxx.__MigrationHistory' 不存在错误

c# - 禁用自动更改检测会在EF中引起哪些错误?