实体框架MySQL tinyint(1)System.Boolean.Parse FormatException [英] Entity Framework MySQL tinyint(1) System.Boolean.Parse FormatException

查看:107
本文介绍了实体框架MySQL tinyint(1)System.Boolean.Parse FormatException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



然后我使用设计器修改了我的 .edmx 文件,这里开始我的问题。 / p>


  • 首先,设计师不会更新 CSDL内容 CS映射内容 .edmx文件的部分。
    所以我自己更新了内容,最后可以编译该项目。



这里是 .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:String未被识别为有效的布尔值
àSystem.Boo thin.Parse(String value)
àSystem.String.System.IConvertible.ToBoolean(IFormatProvider provider)
àSystem.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider)
à MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue,Type targetType)
àMySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 ordinal)
à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(Closure,Shaper)
àSystem.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly [TE ntity](Func`2 constructEntityDelegate,EntityKey entityKey,EntitySet entitySet)
àlambda_method(Closure,Shaper)
àSystem.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(更好的整形器)
à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()
à系统。 Data.Entity.Internal.LazyEnumerator`1.MoveNext()
àSystem.Linq.Enumerable.SingleOrDefault [TSource](IEnumerable`1 source)
àSy (.net.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider。& lt; GetElementFunction& gt; b__2 [TResult](IEnumerable`1序列)
àSystem.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider .ExecuteSingle [TResult](IEnumerable`1 query,Expression 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 方法:

 公共橱柜GetCupboardByGuid(String guid)
{
using(var context = n ew ArmoireOutilsEntities())
{
var cupboard =(from a in context.Cupboards
where a.GUID.Equals(guid)
select a)
.Include (ResidentTools)
.Include(工具)
.Include(Users)//如果我删除这个,.SingleOrDefault()工作正常。
.SingleOrDefault(); //从数据库获取User.Active值时抛出FormatException。

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

返回橱柜;
}
}

这里是由.edmx生成的我的User类tt:

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

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

public virtual Lang Lang {get;组; }
public virtual IList< Tool>工具{get;组; }
public virtual IList< Cupboard>橱柜{get;组; }
}

所以我猜EF正在迭代数据库中的所有用户 cupboarduser (将用户链接到橱柜之间的多对多关系),以及设置第一个用户的活动值,它从数据库中获取1,首先将其作为 String ,然后尝试使用 System.Boolean.Parse将该字符串解析为布尔值,但是thaat方法不支持像1这样的数字(DB中的字段是 tinyint(1))。


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



我试图从数据库中重新生成整个 .edmx 文件=>同样例外



我试图重新生成整个。 edmx 文件从零开始=>同样例外



我不会了解为什么因为我没有修改用户模型,所以 Active 字段已经存在,并且工作正常。



邮寄和感谢提前。



最好的问候,
theCivilian

解决方案

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

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

或一般:

 
.Configure(x => x.HasColumnType(bit) ));


I'm using EntityFramework 6 in my C# model-first project which using a MySQL database. Everything was fine and I could generate my database without problem.

Then I modified my .edmx file using the designer and here started the problems I have.

  • First the designer doesn't update the CSDL content and the C-S mapping content sections of the .edmx file anymore. So I updated the content myself and could finally compile the project.

Here's the .edmx file as it is right now and what it looks like in the designer:

EDMX File: http://pastebin.com/Xer9UyNR

And here is the link for the designer view: http://i.stack.imgur.com/Vcv9W.png

  • Second (and most important one), I get a FormatException when EF tries to get a tinyint coming from my database and change its type into a boolean.

    à ArmoireOutils.App.OnNavigateMessageHandler(OnNavigateMessage message) dans c:\Users\JB\Desktop\CodingFrance\ArmoireOutils\ArmoireOutils\App.xaml.cs:line 101System.FormatException: String was not recognized as a valid Boolean..
    à System.Boolean.Parse(String value)
    à System.String.System.IConvertible.ToBoolean(IFormatProvider provider)
    à System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
    à MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue, Type targetType)
    à MySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 ordinal)
    à 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(Closure , Shaper )
    à System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
    à lambda_method(Closure , Shaper )
    à 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 source)
    à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.&lt;GetElementFunction&gt;b__2[TResult](IEnumerable`1 sequence)
    à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
    à System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
    à System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
    à System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
    à ArmoireOutils.Services.DataService.GetCupboardByGuid(String guid) dans c:\Users\JB\Desktop\CodingFrance\ArmoireOutils\ArmoireOutils\Services\DataService.cs:line 202

Here is my GetCupboardByGUID method:

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

And here is my User class generated by the .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; }
}

So I guess EF is iterating over all users from the DB who are in the cupboarduser (the table linking a user to a cupboard for the many-to-many relationship) and when it comes to set the Active value for the first user, it gets 1 from the DB getting it as a String first and then try to parse that string into a boolean using System.Boolean.Parse but thaat method doesn't support numbers like "1" for true (the field in the DB is a tinyint(1)).

So why EF is not able to understand it was a tinyint so he can't use it in System.Boolean.Parse ?

I tried to regenerate the entire .edmx file from the database => Same exception

I tried to regenerate the entire .edmx file from scratch => Same exception

I don't understand why because I didn't modify the User model so the Active field was already there and was working just fine.

Sorry for the long post and thanks in advance.

Best regards, theCivilian

解决方案

Configure the datatype on a specific Entity:

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

or general:

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

这篇关于实体框架MySQL tinyint(1)System.Boolean.Parse FormatException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆