【问题标题】:The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'“Y”上的“X”属性无法设置为“null”值。您必须将此属性设置为“Int32”类型的非空值
【发布时间】:2012-11-16 15:56:41
【问题描述】:

当我运行我的应用程序并单击特定按钮时出现错误:

"The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'."

太好了,所以我去我的Entity项目,去Y表,找到X列,右键单击并进入X的属性,发现Nullable设置为False。

我在 SQL 中验证,在 Y 表中,X 设置为允许空值,并且确实如此。

然后我回到我的实体项目,将 Nullable 设置为 True,保存并构建,然后我收到:

Error 3031: Problem in mapping fragments starting at line 4049:Non-nullable column "X" in table "Y" is mapped to a nullable entity property.

我听说从 .edmx 文件中删除表然后重新添加它是可能的,但我从未这样做过,也没有充分理解这样做的含义。

听说可以在视图中,也可以在存储过程中……

也听说这是个bug。

有没有人遇到过这种情况并找到了“全面”修复或某种路线图来查找此错误的位置?

谢谢!

【问题讨论】:

  • 您实际尝试过什么?我不知道 .edmx 文件是什么,但您可以简单地尝试按照建议删除/重新添加它。如果这不起作用,请更换为您的原件。您正在使用某种 VCS(版本控制系统),对吧?
  • 您是否在更改实体后更新了您的对象?您可能在 Y 对象中的 X 属性仍定义为 'int' 而不是 'int?'

标签: sql visual-studio-2010 entity-framework


【解决方案1】:
 "The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'."

在您的 EDMX 中,如果您在 Y 表下单击 X 列,右键单击,单击属性,向下滚动到 Nullable 并从 False 更改为 True

如果您收到“映射片段”错误,则必须从 EDMX 中删除表并重新添加它,因为在模型浏览器中它存储表属性以及刷新它的唯一方法(我知道)是从模型浏览器中删除<database>.Store下的表,然后使用Update Model from Database..命令检索它。

【讨论】:

  • 不过这确实是首选答案。
【解决方案2】:

我只是将数据类型 int 替换为 int32?

public Int32 Field{ get; set; }

public Int32? Field{ get; set; }

问题解决了

【讨论】:

  • 非常适合我。感谢您为我节省了大量时间!但是我想指出,这也适用于“int”。这是我的代码:public int? Success { get; set; }
  • 这是最好的非显而易见的答案。我什至还没有尝试过,我很确定这是我的问题。
  • 无法编辑我的答案。是的,更改为可空类型确实解决了我的问题。
【解决方案3】:

我的问题是我的模型数据库与实际(开发)数据库不同步。所以 EDMX 认为它是 smallint 但实际的列是 int。我将模型数据库更新为 int,将 EDMX 更新为 Int32,现在它可以工作了。

【讨论】:

  • (使用 MVC)字段在 DB 中定义为 Small Int,但在模型中定义为 Int。将模型中的 def 更改为 Int16。问题解决了。
【解决方案4】:

为未来的读者。

当我有一个多结果存储过程时出现此错误。

如下所示:

http://msdn.microsoft.com/en-us/data/jj691402.aspx

如果您尝试访问第一个结果中的项目,在执行.NextResult 后,您可能会收到此错误。

来自文章:

    var reader = cmd.ExecuteReader();

    // Read Blogs from the first result set
    var blogs = ((IObjectContextAdapter)db)
        .ObjectContext
        .Translate<Blog>(reader, "Blogs", MergeOption.AppendOnly);   


    foreach (var item in blogs)
    {
        Console.WriteLine(item.Name);
    }        

    // Move to second result set and read Posts
    reader.NextResult();
    var posts = ((IObjectContextAdapter)db)
        .ObjectContext
        .Translate<Post>(reader, "Posts", MergeOption.AppendOnly);


    foreach (var item in posts)
    {
        Console.WriteLine(item.Title);
    }

现在,如果之前

foreach (var item in posts)

你输入了这段代码

Blog foundBlog = blogs.FirstOrDefault();

我认为你可以模拟错误。

经验法则:

你还是要把这个东西当成DataReader(消防水管)。

出于我的需要,我不得不转换为List&lt;&gt;

所以我改变了这个:

    foreach (var item in blogs)
    {
        Console.WriteLine(item.Name);
    }  

到这里:

    List<Blog> blogsList = blogs.ToList();
    foreach (var item in blogsList )
    {
        Console.WriteLine(item.Name);
    }  

而且我能够导航对象而不会出现错误。

这是我遇到的另一种方式。

    private void DoSomething(ObjectResult<Blog> blogs, ObjectResult<Post> posts)
    {

    }

然后在这段代码之后(在原始示例中)

foreach (var item in posts)
{
    Console.WriteLine(item.Title);
}

输入这段代码:

DoSomething(blogs,posts);

如果我调用该例程并开始访问博客和帖子中的项目/属性,我会遇到这个问题。我明白为什么,我应该第一次抓住它。

【讨论】:

  • 我有一个返回多个集合的存储过程,我发现如果我将该字段转换为正确的类型,它就会解决这个问题。如果它是 0,数据库将假定它是一个 int 而不是一点点。由于所有内容都是强制转换的,因此一旦您转换了任何可能被错误转换的字段,它就不再是问题了。
【解决方案5】:

我确认实体指向正确的数据库。

然后我从 .edmx 文件中删除了该表并再次添加它。

问题解决了。

【讨论】:

    【解决方案6】:

    检查你的模型和数据库都应该相应地定义......

    公共 Int32? X { 得到;放; } ----> 可以为空 因此在 DB 'X' 中应该为 Nullable = True

    公共 Int32 X { 获取;放; } ----> 不可为空 因此在 DB 'X' 中应该为 Nullable = false

    【讨论】:

      【解决方案7】:

      在我选择的包含空值的 DB 列中创建的视图中,我通过此 select 语句更改了该值:

      在我改变之前

       select 
           ..., GroupUuId , ..
      

      改变后

       select 
           ..., ISNULL(GroupUuId, 0), ... 
      

      对不起我的英语不好

      【讨论】:

        【解决方案8】:

        当数据库表允许 NULL 并且存在具有空值的记录并且您尝试使用 EF 读取此记录并且映射类不允许空值时,可能会发生这种情况。

        解决方案是更改数据库表使其不允许 null 或更改您的类以允许 null。

        【讨论】:

          【解决方案9】:

          对我来说,以下步骤纠正了错误:

          1. 从“Y”表中删除“X”属性
          2. 保存 EDMX
          3. 从模型构建数据库
          4. 编译
          5. 再次将“X”属性添加到“Y”表(不可为空和 int16)
          6. 保存 EDMX
          7. 从模型构建数据库
          8. 编译

          【讨论】:

            【解决方案10】:

            修复错误

             Error 3031: Problem in mapping fragments starting at line 4049:Non-nullable column "X" in table "Y" is mapped to a nullable entity property.
            

            使用 xml 编辑器打开您的 EDMX 文件并在

            中查找您的表格

            edmx:StorageModels

            找到给出错误的属性并设置或添加

            Nullable="false" >> 到 Nullable="true"

            保存 edmx,在 Visual Studio 中打开并构建它。问题解决了

            【讨论】:

              【解决方案11】:

              遇到相同的错误但上下文不同,尝试使用 linq 连接表,其中对于数据库中的一个表,非空列插入了空值,将值更新为默认值,问题已修复。

              【讨论】:

              • 非空列不可能有“插入空值”。另外,这并没有回答最初的问题,发布这个真的有帮助吗?
              • 其实可以Gert,如果表定义已经更新了No Check。
              • @GertArnold,正如 ARLibertarian 回答的那样,非空列可能为空。正如明确提到的那样,上下文不同,但问题相似。希望它可以帮助某人节省时间。我的学习,遗留数据库数据设计错误。
              猜你喜欢
              • 2017-11-25
              • 1970-01-01
              • 2014-12-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多