【问题标题】:Entity Framework MySQL tinyint(1) System.Boolean.Parse FormatException实体框架 MySQL tinyint(1) System.Boolean.Parse FormatException
【发布时间】:2014-09-24 15:50:30
【问题描述】:

我在使用 MySQL 数据库的 C# model-first 项目中使用 EntityFramework 6 一切都很好,我可以毫无问题地生成我的数据库。

然后我使用设计器修改了我的 .edmx 文件,这里开始出现我遇到的问题。

  • 首先,设计者不再更新 .edmx 文件的 CSDL 内容C-S 映射内容 部分。 于是我自己更新了内容,终于可以编译项目了。

这是 .edmx 文件,它现在的样子以及它在设计器中的样子:

EDMX 文件:http://pastebin.com/Xer9UyNR

这里是设计器视图的链接: http://i.stack.imgur.com/Vcv9W.png

  • 第二个(也是最重要的一个),当 EF 尝试从我的数据库中获取一个 tinyint 并将其类型更改为布尔值时,我得到一个 FormatException。
à ArmoireOutils.App.OnNavigateMessageHandler(OnNavigateMessage message) dans c:\Users\JB\Desktop\CodingFrance\ArmoireOutils\ArmoireOutils\App.xaml.cs:line 101System.FormatException: 字符串未被识别为有效布尔值。 à System.Boolean.Parse(字符串值) à System.String.System.IConvertible.ToBoolean(IFormatProvider 提供者) à System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) à MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue, Type targetType) à MySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 序数) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetUntypedValueDefault(DbDataReader reader, Int32 ordinal) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32 ordinal, String propertyName, String typeName) à lambda_method(闭包,整形器) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2constructEntityDelegate, EntityKey entityKey, EntitySet entitySet) à lambda_method(闭包,整形器) à System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MaterializeRow() à System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MoveNext() à System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.TryReadToNextElement() à System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.ReadElement() à System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.MoveNext() à System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() à System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 源) à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2[TResult](IEnumerable`1 序列) à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 查询,表达式 queryRoot) à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](表达式表达式) à System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](表达式表达式) à System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 源) à ArmoireOutils.Services.DataService.GetCupboardByGuid(String guid) dans c:\Users\JB\Desktop\CodingFrance\ArmoireOutils\ArmoireOutils\Services\DataService.cs:line 202

这是我的 GetCupboardByGUID 方法:

public Cupboard GetCupboardByGuid(String guid)
    {
        using (var context = new ArmoireOutilsEntities())
        {
            var cupboard = (from a in context.Cupboards
                where a.GUID.Equals(guid)
                select a)
                .Include("ResidentTools")
                .Include("Tools")
                .Include("Users") //If I remove this, .SingleOrDefault() works fine.
                .SingleOrDefault(); //Throw FormatException when getting the User.Active value from the database.

            if (cupboard != null)
                cupboard.RefreshLists();

            return cupboard;
        }
    }

这是由 .edmx tt 生成的我的用户类:

public partial class User
{
    public User()
    {
        this.Tools = new ObservableCollection<Tool>();
        this.Cupboards = new ObservableCollection<Cupboard>();
        this.Active = true;
    }

    public int Id { get; set; }
    public short Type { get; set; }
    public string Firstname { get; set; }
    public string LastName { get; set; }
    public string Login { get; set; }
    public short Gender { get; set; }
    public short LangId { get; set; }
    public string Photo { get; set; }
    public System.DateTime CreationDate { get; set; }
    public Nullable<System.DateTime> ModificationDate { get; set; }
    public Nullable<System.DateTime> LastConnection { get; set; }
    public Nullable<System.DateTime> DisableDate { get; set; }
    public bool Active { get; set; }

    public virtual Lang Lang { get; set; }
    public virtual IList<Tool> Tools { get; set; }
    public virtual IList<Cupboard> Cupboards { get; set; }
}

所以我猜 EF 正在遍历数据库中在 cupboarduser 中的所有用户(将 user 链接到 cupboard 的表对于多对多关系),当为第一个用户设置 Active 值时,它会从数据库中获取 1,首先将其作为 String 并然后尝试使用 System.Boolean.Parse 将该字符串解析为布尔值,但该方法不支持像“1”这样的数字为真(数据库中的字段是 tinyint(1 ))。

那么为什么 EF 无法理解它是一个 tinyint,所以他不能在 System.Boolean.Parse 中使用它?

我试图从数据库中重新生成整个 .edmx 文件 => 相同的异常

我尝试从头开始重新生成整个 .edmx 文件 => 相同的异常

我不明白为什么,因为我没有修改 User 模型,所以 Active 字段已经存在并且工作正常。

抱歉发了这么长的帖子,提前感谢。

最好的问候, 平民

【问题讨论】:

  • 你必须告诉 MySql 在连接字符串中将 tinyint 视为布尔值。
  • @GertArnold,感谢您的建议,但不幸的是它说 “不支持 'treat tiny as boolean' 关键字。” 这个值也是 true 默认情况下根据文档。 (我正在使用 MySQL-Connector 6.8.3

标签: c# mysql entity-framework visual-studio-2013


【解决方案1】:

在特定实体上配置数据类型:

modelBuilder.Entity<User>()
                  .Property(p => p.Active)
                  .HasColumnType("bit");

或一般:

modelBuilder.Properties()
            .Where(x => x.PropertyType == typeof(bool))
            .Configure(x => x.HasColumnType("bit"));

【讨论】:

  • 如果我们先做数据库,有没有办法做到这一点?不确定在哪里应用更改。帮忙?
  • 这对我来说就像一个魅力,我使用了 TINYINT(1),但是当我尝试检索数据时它不起作用,但是使用 BIT 类型对于保存和检索数据都很好。
【解决方案2】:

这也可以使用实体中的Column 数据属性来实现。

[Column("Active", TypeName = "bit")]
[DefaultValue(false)]
public bool Active { get; set; }

【讨论】:

  • 据我所知,这里不需要默认值属性。
【解决方案3】:

如果您首先执行此 DB,只需将 TINYINT(1) 类型更改为 BIT(1),假设您确实想要一个布尔值。您可能还必须更新默认值(以位语法,例如 b'0')。 EF 仍会将这些转换为实体中的布尔值。

【讨论】:

    【解决方案4】:

    我实际上不得不在连接字符串中设置 TreatTinyAsBoolean=false 并且我的问题得到了解决。

    【讨论】:

      猜你喜欢
      • 2012-09-04
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-07
      • 2015-07-11
      • 2020-08-12
      相关资源
      最近更新 更多