【问题标题】:The 'x' property on 'y' could not be set to a 'System.Decimal' value. You must set this property to a non-null value of type 'System.Boolean''y' 上的 'x' 属性无法设置为 'System.Decimal' 值。您必须将此属性设置为“System.Boolean”类型的非空值
【发布时间】:2017-11-25 08:36:44
【问题描述】:

我有一个 MySQL 存储过程,从名为 tuser 的特定表中选择数据。

我使用的是EntityFramework6,所以我将过程的结果定义为tuser的实体。

当我在 C# 代码中使用该过程时,抛出以下异常:

“tuser”上的“bIsActive”属性无法设置为“System.Decimal”值。您必须将此属性设置为“System.Boolean”类型的非空值。

我无法理解我想要执行的操作与引发的异常之间的联系。

数据库中的表定义:

CREATE TABLE `tuser` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sUserName` varchar(45) DEFAULT NULL,
`sUserNameMail` varchar(45) DEFAULT NULL,
`sMail` varchar(45) DEFAULT NULL,
`bIsActive` bit(1) DEFAULT b'1')
 ENGINE=InnoDB AUTO_INCREMENT=2225 DEFAULT CHARSET=utf8;

ef中的bIsActive定义:

存储过程定义:

CREATE DEFINER=``@`` PROCEDURE `GetActiveUsers`()
BEGIN
  select u.* from tuser u
  where u.bIsActive=true;
END

执行以下代码行时发生错误:

List<tuser> list = Context.GetActiveUsers().ToList();

内部 GetActiveUsers 代码(自动生成):

public virtual ObjectResult<tuser> GetActiveUsers()
{    
   return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<tuser>("GetActiveUsers");
}

【问题讨论】:

  • 看起来你有一个布尔值并且你试图将它设置为十进制? tuser.blsActive 是布尔值,而不是小数。
  • 显示在tuser 中将blsActive 分配为bool 属性的任何代码。
  • “这就是重点”——那为什么不在问题中呢? 在问题中包含所有相关信息。您能否发布一个演示该问题的存储过程的简短示例? (它不需要是真正的 SP - 只需一个表现出相同行为的 SP。)
  • select * from tuser where bIsActive=true 是一个错误的分配。试试select * from tuser where bIsActive=1
  • @Ariela:我并不是建议在代码中使用查询。我只是想帮你诊断出了什么问题。如果查询有效而存储过程无效,则需要查看数据库返回的内容有何不同。

标签: c# mysql entity-framework stored-procedures


【解决方案1】:

好的,感谢所有响应者。

我仍然不知道是什么问题,但是当我从模型中删除 tuser 表并重新添加时,问题已经解决了。

【讨论】:

  • 我想这个问题是在生成的代码/模型中的某处损坏。干得好阿瑞拉!
  • 这就是为什么我说属性是十进制的。它在代码库中是十进制的。您只更新了 EDMX 模型,但没有更新生成的代码。
  • @GertArnold2 这不是您在屏幕截图中看到的那样。
【解决方案2】:

异常告诉我们布尔变量 bIsActive 被分配了一个 decimal 或者没有在以下行周围的某个地方正确转换:

List<tuser> list = Context.GetActiveUsers().ToList();

因此,解决方案是从引发异常到错误分配值的过程。

首先,尝试改变...

public virtual ObjectResult<tuser> GetActiveUsers()
{    
    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<tuser>("GetActiveUsers");
}

...与...

public virtual ObjectResult<tuser> GetActiveUsers()
{
    try
    {
        Stringbuilder sb = new Stringbuilder();

        IObjectContextAdapter a = ((IObjectContextAdapter)this); // Breakpoint this line and F11 step through the code, looking at local variables as you go

        sb.AppendLine(", a: " + a.ToString());

        var b = a.ObjectContext;

        sb.AppendLine(", b: " + b.ToString());

        var c = b.ExecuteFunction<tuser>("GetActiveUsers");

        sb.AppendLine(", c: " + c.ToString());

        MessageBox.Show("No exception: (" + sb.ToString() + ")");

        return c;

    }
    catch(Exception ex)
    {
        MessageBox.Show("Exception: (" + ex.message + ex.stacktrace + ")");

    }

}

我希望你能看到我在那里尝试做的事情,即将代码分成小块并研究每个块的输出。消息框消息告诉你是否抛出异常,并会给出StackTrace,这对这样的旅程非常有帮助。

  • 替换方法
  • 运行程序
  • 将 MessageBox 的屏幕截图粘贴到您的帖子中

下一步可能是查看数据库函数GetActiveUsers

您如何管理您的 MySql 数据库?你使用 MySql 工作台还是其他接口?您应该可以从那里查看该函数。

【讨论】:

  • 为什么你认为它是连接的?但是,它不起作用。
  • 鉴于原始代码 编译 正常,我看不到类型推断导致问题的迹象。为什么您认为这会有所作为?
  • @JonSkeet 请冷静下来,乔恩。异常在List&lt;tuser&gt; list = Context.GetActiveUsers().ToList(); 行被抛出,但这仅暗示我们如何发现解决方案。在寻找解决方案时,我喜欢从北、南、东和西接近。
  • 如果您要求进行更多诊断,最好在 cmets 中完成 - 特别是如果它包含诸如此类的虚假建议,IMO。
  • 当然 - 作为评论。不作为答案;它不能解决OP的问题。老实说,要求完整的堆栈跟踪会以一种相当简单的方式完成此操作……如果这没有表明ExecuteFunction 正在抛出异常,我会感到惊讶;直到那时的局部变量并没有真正的帮助。我仍然认为这是“没有用”的答案,因此投反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 2016-01-19
相关资源
最近更新 更多