查找/更新中的 EF 4.1 Code First 错误。有什么解决办法吗?是否应该报告?

2024-06-04

我在 EF 4.1 Code First 中发现了一个非常严重的错误。假设我们有这段代码从上下文中检索一个实体,然后用新值更新它:

public T Update<T>(T toUpdate) where T : class
        {
            System.Data.Objects.ObjectContext objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)_context).ObjectContext;
            System.Data.Objects.ObjectSet<T> set = objectContext.CreateObjectSet<T>();
            IEnumerable<string> keyNames = set.EntitySet.ElementType
                                                        .KeyMembers
                                                        .Select(k => k.Name);
            var type = typeof(T);
            var values = keyNames.Select(c => type.GetProperty(c).GetValue(toUpdate, null)).ToArray();
            var current = _context.Set<T>().Find(values);
            if (current != null)
            {
                _context.Entry(current).CurrentValues.SetValues(toUpdate);
            }
            return current;
        }

现在假设我的实体有一个键属性,它是一个字符串。

工作场景:存储的实体具有键“ABCDE”,我的 toUpdate 实体具有相同的键“ABCDE”:一切正常。

错误场景:存储的实体具有键“ABCDE”,而我的 toUpdate 实体具有键“ABCDE”(注意最后一个字母后面的空格)。

这两个键确实不同。但 find 方法“自动”修剪我的密钥并找到存储的实体。如果它没有破坏 SetValues 方法,那就太好了:由于存储的密钥和新的密钥不同,我得到(正确的)以下内容:

属性“Id”是对象关键信息的一部分,不能 被修改。

因为,不同的是,它尝试更新它,并且由于它是一个关键属性,所以无法更新,所以整个事情都会失败并抛出。

我认为“查找”方法不应该自动修剪键值(或者它在内部所做的任何事情以使两个不同的字符串看起来相同)。在第二种情况下,“Find”方法应返回 null。

现在有两件事:我如何暂时解决这个问题,以及我可以在哪里报告这个错误,因为我找不到报告该错误的官方位置。

Thanks.

编辑:在这里报告错误:https://connect.microsoft.com/VisualStudio/feedback/details/696352/ef-code-first-4-1-find-update-bug https://connect.microsoft.com/VisualStudio/feedback/details/696352/ef-code-first-4-1-find-update-bug


但是 find 方法“自动”修剪我的密钥并找到存储的 无论如何实体。

我不相信会发生修剪。Find uses a SingleOrDefault内部查询,换句话说:当您调用...

set.Find("ABCDE "); // including the trailing blank

...它使用这个 LINQ 查询:

set.SingleOrDefault(key => key == "ABCDE "); // including the trailing blank

问题出在数据库中,结果取决于排序顺序、语言、大写/小写字母设置、重音等。string数据库中的关键字段(nvarchar(10)例如)。

例如,如果您使用标准Latin1_GeneralSQL Server 中键的排序顺序"ABCDE" and "ABCDE "(尾随空白)相同,您无法创建以这些值作为主键的两行。甚至"ABCDE" and "abcde"是相同的(如果您没有在 SQL Server 中设置区分大小写字母)。

同时这意味着也查询stringcolumns 将返回所有匹配的行 - 与数据库中该列的排序顺序匹配。查询为"ABCDE "尾随空白只会返回一条记录"ABCDE"没有尾随空白。

到目前为止,对于所有涉及字符串的 LINQ to Entities 查询来说,这是“正常”行为。

现在,正如您所发现的那样,ObjectContext 似乎不知道数据库中配置的排序顺序,并使用正常的 .NET 字符串比较,其中带尾随空格的字符串和不带尾随空格的字符串是不同的。

我不知道是否可以告诉上下文使用与数据库相同的字符串比较。我有些怀疑这是否可能,因为 .NET 世界和关系数据库世界太不同了。某些排序顺序可能很特殊,仅在数据库中可用,而在 .NET 中根本不可用,反之亦然。此外,除了 SQL Server 之外,还有其他数据库必须受到实体框架的支持,并且这些数据库可能有自己的排序系统。

对于您的具体情况 - 也许总是当您有string键 - 问题的可能解决方法是将实体的 key 属性设置为更新为从数据库返回的对象的键:

toUpdate.Id = current.Id;
_context.Entry(current).CurrentValues.SetValues(toUpdate);

或者更一般地说,在您的代码上下文中:

//...
var current = _context.Set<T>().Find(values);
if (current != null)
{
    foreach (var keyName in keyNames)
    {
        var currentValue = type.GetProperty(keyName).GetValue(current, null);
        type.GetProperty(keyName).SetValue(toUpdate, currentValue, null);
    }
    _context.Entry(current).CurrentValues.SetValues(toUpdate);
}

toUpdate不得附加到上下文才能使其正常工作。

这是一个错误吗?我不知道。至少这是 .NET 和关系数据库世界之间不匹配的结果,也是避免的一个很好的理由string首先是关键列/属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找/更新中的 EF 4.1 Code First 错误。有什么解决办法吗?是否应该报告? 的相关文章

  • Entity Framework Core - 在 Queryable 中使用扩展方法

    我有以下查询 db Users AsQueryable Where u gt u Id userResolver LoggedUserId u Packages Where p gt p StatusId int PackageStatus
  • C# 属性实际上是方法吗?

    到现在为止 我的印象是Properties Methods在 C 中是两个不同的东西 但后来我做了如下的事情 这对我来说是 大开眼界 我本来期待一处房产stringProp和一种方法stringProp但我得到了这个 为什么会发生这样的事
  • WiX - 安装 Windows 服务并授予权限

    我们需要授予用户启动 停止和查询已安装服务状态的权限 在 WiX 2 0 中 这个 xml 可以工作
  • 启用 useLegacyV2RuntimeActivationPolicy 的影响?

    对于我当前的项目 我们使用一些基于 CLR 2 的混合模式程序集 为了在 NET 4 目标程序集中使用这些 我知道您必须添加useLegacyV2RuntimeActivationPolicy true to the
  • 如何添加新的进度条来显示总体下载?

    代码正在运行 但是 现在我显示每个文件的下载进度progressBar1 但我想添加到设计器 已经添加 progressBar2显示总体下载进度 我如何计算并显示它progressBar2 using System using System
  • 检查输出是否重定向

    我有一个用 C 编写的控制台应用程序 它处理一些数据然后打印结果 在结果可用之前 会有一个小动画 和不断更新的进度百分比 xx 显然 如果用户重定向我的应用程序的输出 这将被打印到输出重定向到的文本文件中 如果可能的话我想避免这种情况 那么
  • 部署.Net应用程序

    我在部署 net windows 应用程序时确实有某些疑问 部署机器是否需要安装 Net框架 如果不是这样 我的应用程序安装程序 exe 是否包含编译器或类库与设置集成 另外 我可以将我的 net 应用程序部署在除windows 是否支持s
  • .NET:为什么不检查枚举的范围/值?

    这一直困扰着我 也许对 NET 内部结构有一定了解的人可以向我解释一下 假设我定义一个枚举如下 public enum Foo Eenie 1 Meenie 2 Miney 3 Moe 4 现在 还假设我的代码中的某处有以下代码 int b
  • 指定自定义序列化程序时,错误详细信息未反序列化

    我正在使用自定义XmlObjectSerializer在我的应用程序中 为此 我替换XmlSerializerOperationBehavior with MyOperationBehavior看起来像这样 public class MyO
  • CLR 内部字符串常量吗?

    最近我一直在阅读字符串实习生池的工作原理 然而我一直没能找到这个问题的答案 如果我声明一个常量字符串变量 例如const string STR foo 这是否也会添加到实习生表中 只是为了澄清事情 CLR 不参与字符串驻留 Internin
  • Linq Any 始终返回 true

    我已经使用 Linq to Entities 多年 但这是我第一次遇到这个问题 我有Tips and Items表 每个提示可以有很多项目 我的数据库中只有 3 个项目 编辑项目时 我想确保GivenId对于具有相同提示的项目 字段是唯一的
  • 在实体框架中不使用 Dispose 或 using()

    我一路上正在编写一个网络应用程序并学习实体框架 如果我做错了什么 我很好奇 我在查询时没有使用过 dispose 或 using 语句 我的存储库示例 public User GetUserById int sessionId var us
  • TPL架构问题

    我目前正在开展一个项目 我们面临并行处理项目的挑战 到目前为止没什么大不了的 现在来说说问题 我们有一个 ID 列表 我们定期 每 2 秒 为每个 ID 调用一个 StoredProcedure 需要单独检查每个项目的 2 秒 因为它们是在
  • EntLib5:登录应用程序块未记录到事件日志(例外:无法构造 LogWriter 类型)-任何人都可以帮忙吗?

    你好呀 我刚刚设置了 Enterprise Library 5 的日志记录应用程序块部分 我认为我已经完成了正确的操作 但它没有记录到事件日志 它在写入方法上出错并给出了以下异常 The type LogWriter cannot be c
  • 通过名称获取枚举成员的值?

    假设我有一个变量 其值 例如 listMovie 是一个名称enum member public enum Movies regMovie 1 listMovie 2 member whose value I want 在此示例中 我想获取
  • invalidate方法有什么作用?

    什么是invalidate方法做在winform app Invalidate method附带六超载里面形成control class of System Windows Forms 名称空间 谢谢 Windows 窗体使用 GDI 进行
  • 如何检查应用程序的另一个实例是否正在运行[重复]

    这个问题在这里已经有答案了 有人可以展示如何检查程序的另一个实例 例如 test exe 是否正在运行 如果是 则停止加载应用程序 如果存在该实例 想要一些严肃的代码吗 这里是 var exists System Diagnostics P
  • 在运行时从调试可视化工具中检测源语言

    我正在写一个Visual Studio 的调试可视化工具 https github com zspitz ExpressionToString visual studio debugger visualizer for expression
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用

随机推荐

  • 从 CSS 调用 javascript 函数

    我想知道是否有可能以任何方式 button width somePX height somePX button hover onmouseup func button 或类似的东西 我想这会有点酷吗 而不是为每个按钮编写 onmouseup
  • 如何通过ndk将android相机帧加载到opengl es纹理中?

    我最近一直在研究opengl es并尝试在android平台上访问相机 我需要做的就是通过ndk逐帧加载相机数据 然后加载到GL纹理中进行进一步处理 有什么帮助或建议吗 如果有示例代码 将不胜感激 谢谢你 将相机输出发送到 SurfaceT
  • 如何使用实体框架 Fluent API 配置多对多关系

    我试图首先在 EF 代码中建立多对多关系 但默认约定是错误的 以下类描述了这种关系 class Product public int Id get set public string Name get set class Account p
  • 实体框架 - 从 ObjectContext 查询与从导航属性查询

    我注意到 根据从实体框架模型中提取数据的方式 我会得到不同类型的结果 例如 获取特定部门的员工列表时 如果我直接从 ObjectContext 中提取 我会得到一个IQueryable
  • 如何使用 Libsodium-PHP 加密/解密 AES

    我需要用 PHP 加密 解密数据 我对此完全陌生 但是我读到 Libsodium PHP 是 AES 加密的最佳工具 就像我研究过的其他 PHP 加密库一样 Libsoduim PHP 似乎几乎没有提供如何使用该库的文档 我能够找到 任何有
  • Swagger 返回“规范中没有定义操作!” [复制]

    这个问题在这里已经有答案了 我正在开发一个 NET Core 3 1 Web API 应用程序 我正在盯着这个屏幕 https i stack imgur com W4IXK png一阵子 我已经安装了Swashbuckle AspNetC
  • 运行连接到 Django 测试数据库的 Celery Worker

    背景 我正在开发一个项目 该项目使用 Celery 来安排将在未来某个时间运行的任务 这些任务推动最终状态机的状态向前发展 这是一个例子 未来的提醒计划在 2 天内发送给用户 当该计划任务运行时 会发送一封电子邮件 并且 FSM 会前进到下
  • 如何获取列名列表

    是否可以像这样获取包含表的所有列名的行 id foo bar age street address 我不喜欢用Pragma table info bla SELECT sql FROM sqlite master WHERE tbl nam
  • 嵌入定义绑定变量的 Oracle PL/SQL 代码的 Shell 脚本

    如果我运行下面的脚本 我会收到错误SP2 0552 未声明绑定变量 OUTRES 那么 如何定义绑定变量OUTRES以及在哪里定义呢 usr bin bash sqlplus s scott tiger lt lt EOF declare
  • JTextPane 的等宽字体/符号

    我想使用 JTextPane 构建类似控制台的输出 因此我使用等宽字体 textpane setFont new Font Font MONOSPACED Font PLAIN 12 这适用于所有类型的字母 如 a z 0 9 等 字符 但
  • CodeDomProvider.CompileAssemblyFromSource - 找不到 Roslyn (csc.exe)

    我们最近从旧的 CodeDomProvider 升级到名为 Microsoft CodeDom Providers DotNetCompilerPlatform 的新 Roslyn CodeDomProvider 它工作正常 但它在错误的位
  • 如果 EditText 为空,如何禁用按钮?

    我的应用程序中有一个 EditText 和一个按钮 单击该按钮时 在 EditText 中输入的文本将添加到 ListView 中 如果 EditText 为空 我想禁用按钮 如何做到这一点 这是我的按钮点击代码 ImageButton i
  • 使用隐式转换运算符的 Nullable 行为的理由是什么

    我在人与人之间的互动中遇到了一些有趣的行为Nullable和隐式转换 我发现为引用类型提供从值类型的隐式转换它允许Nullable当我期望出现编译错误时 类型将传递给需要引用类型的函数 下面的代码演示了这一点 static void Mai
  • 在 TypeScript 中创建 swagger Web 服务的正确方法是什么

    我是用 TypeScript 编写的项目的一部分 我正在尝试添加与 Swagger 兼容的 TypeScript Web 服务器 考虑到易于维护性 实现它的最基本策略是什么 对于 Typescript 我注意到存在 Typson 库 用于从
  • 在 WP7 中,当页面上存在 WebBrowser 控件时,TextBox.Focus() 不起作用

    我需要将焦点设置在文本框上 问题是 当页面上存在 WebBrowser 控件时 SIP 会显示为就像选择了文本框一样 但光标在文本框中不可见 并且输入不会转到文本框 如果我注释掉 WebBrowser 控件 则行为如预期 加载页面时光标在文
  • 在 tumblr 主题中显示当前年份

    我想在我的 Tumblr 主题的页脚中放置一个版权声明 例如 Acme Co 2013 但我不想每年都进行更新 通常使用 php 可以使用date 这很好 但是虽然 Tumblr 是基于 php 构建的 但我认为最终用户不能在网站上使用它
  • 使用 ``magrittr::`%>%` `` 时 magrittr 管道出错

    不管出于什么原因我在玩magrittr管道语法 并遇到一个奇怪的错误 当您 scope 显式限定调用时发生 gt 我知道使用下面的语法会破坏管道的用途 但我很好奇为什么会发生错误 第一次致电sum按预期工作并输出1 第二次调用会导致错误 E
  • 将 C++ 数组传递给 Ada95

    我正在尝试将无符号整数数组从 C 传递到 Ada Ada Lovelace 教程指出 Ada 数组对应于 C 中指向数组第一个元素的指针 这就是我正在尝试做的事情 C unsigned int buffer bufferSize unsig
  • Pandas DatetimeIndex 与 to_datetime 差异

    我正在尝试将 Pandas 系列纪元时间戳转换为人类可读的时间 至少有两种明显的方法可以做到这一点 pd DatetimeIndex and pd to datetime 它们似乎以完全不同的方式工作 In 1 import pandas
  • 查找/更新中的 EF 4.1 Code First 错误。有什么解决办法吗?是否应该报告?

    我在 EF 4 1 Code First 中发现了一个非常严重的错误 假设我们有这段代码从上下文中检索一个实体 然后用新值更新它 public T Update