带有 MySQL 连接器 6.4.3 的实体框架 4 自动生成表导致“列长度”异常

Posted

技术标签:

【中文标题】带有 MySQL 连接器 6.4.3 的实体框架 4 自动生成表导致“列长度”异常【英文标题】:Entity Framework 4 with MySQL connector 6.4.3 autogenerate tables causes "Column Length" exception 【发布时间】:2011-07-06 20:23:40 【问题描述】:

我正在使用 Code First 方法处理 mysql 和 .Net EntityFramework 4。 mysql 连接器版本是 6.4.3。

当我第一次运行项目时,我的初始化程序尝试“DropCreateDatabaseAlways”。创建数据库以及所有表。然后抛出以下异常。

Column length too big for column 'ModelHash' (max = 21845); use BLOB or TEXT instead
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: MySql.Data.MySqlClient.MySqlException: Column length too big for column 'ModelHash' (max = 21845); use BLOB or TEXT instead

Source Error:

Line 38: public virtual List GetAll() Line 39: Line 40: return dbSet.ToList(); Line 41: Line 42:

Source File: C:\Users\Andrew\Documents\Visual Studio 2010\Projects\SearchCore\OnlineID.DAL\GlobalGatewayRepository.cs Line: 40

Stack Trace:

[MySqlException (0x80004005): Column length too big for column 'ModelHash' (max = 21845); use BLOB or TEXT instead] MySql.Data.MySqlClient.MySqlStream.ReadPacket() +198 MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& insertedId) +73 MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int32& insertedId) +20 MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force) +100 MySql.Data.MySqlClient.MySqlDataReader.NextResult() +836 MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) +1399 MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() +36 MySql.Data.MySqlClient.MySqlScript.Execute() +551 MySql.Data.MySqlClient.MySqlProviderServices.DbCreateDatabase(DbConnection connection, Nullable1 commandTimeout, StoreItemCollection storeItemCollection) +260 System.Data.Objects.ObjectContext.CreateDatabase() +84 System.Data.Entity.Internal.DatabaseOperations.CreateIfNotExists(ObjectContext objectContext) +28 System.Data.Entity.Database.CreateIfNotExists() +53 System.Data.Entity.DropCreateDatabaseAlways1.InitializeDatabase(TContext context) +233 System.Data.Entity.<>c__DisplayClass21.<SetInitializerInternal>b__0(DbContext c) +75 System.Data.Entity.Internal.<>c__DisplayClass5.<PerformDatabaseInitialization>b__3() +19 System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) +72 System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() +169 System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) +7 System.Data.Entity.Internal.RetryAction1.PerformAction(TInput input) +118 System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action1 action) +190 System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() +73 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +27 System.Data.Entity.Internal.Linq.InternalSet1.Initialize() +62 System.Data.Entity.Internal.Linq.InternalSet1.GetEnumerator() +15 System.Data.Entity.Infrastructure.DbQuery1.System.Collections.Generic.IEnumerable.GetEnumerator() +40 System.Collections.Generic.List1..ctor(IEnumerable1 collection) +315 System.Linq.Enumerable.ToList(IEnumerable1 source) +58 OnlineID.DAL.GlobalGatewayRepository1.GetAll() in C:\Users\Andrew\Documents\Visual Studio 2010\Projects\SearchCore\OnlineID.DAL\GlobalGatewayRepository.cs:40 OnlineID.BAL.AccountService.GetAccounts() in C:\Users\Andrew\Documents\Visual Studio 2010\Projects\SearchCore\OnlineID.BAL\AccountService.cs:32 OnlineID.Website.Controllers.AccountManagement.AccountManagementController.Index() in C:\Users\Andrew\Documents\Visual Studio 2010\Projects\SearchCore\OnlineID.Website\Controllers\AccountManagement\AccountManagementController.cs:29 lambda_method(Closure , ControllerBase , Object[] ) +62 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +208 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27 System.Web.Mvc.<>c_DisplayClass15.b_12() +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 parameters) +191 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343 System.Web.Mvc.Controller.ExecuteCore() +116 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10 System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37 System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21 System.Web.Mvc.Async.<>c__DisplayClass81.b__7(IAsyncResult ) +12 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.<>c_DisplayClasse.b_d() +50 System.Web.Mvc.SecurityUtil.b_0(Action f) +7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8920029 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

我不确定这个“ModelHash”列是什么,因为它在我的模型中不存在。

谢谢, 弗里兹


我已经确定了这个 ModelHash 列的位置,它位于用于跟踪更改的 EdmMetadata 表中。我遇到的错误可以通过添加以下 modelBuilder.Conventions.Remove(); 来消除。那么有没有办法将 EdmMetadata 与 MySQL 一起使用?

【问题讨论】:

我已经确定了这个 ModelHash 列的位置,它在用于跟踪更改的 EdmMetadata 表中。通过添加以下 modelBuilder.Conventions.Remove(); 可以消除我遇到的错误那么有没有办法将 EdmMetadata 与 MySQL 一起使用? 嗨 AFrieze,我无法在 mysql 中先通过代码创建具有 tinyint(byte 或 sbyte) 数据类型的列。你知道解决办法是什么吗? 我没有。你能用布尔值代替字节吗? bool 将在数据库中创建为 tinyint(1) 列。 尝试这样的事情:使用 System.Data.Linq.Mapping; [Column(DbType = "tinyint(4)")] 【参考方案1】:

IncludeMetadataConvention 仅映射 EdmMetadata 实体。

void IConfigurationConvention.Apply(ModelConfiguration modelConfiguration)

    modelConfiguration.Entity(typeof(EdmMetadata), false).ToTable("EdmMetadata");

AFAI 看到框架只是在其他地方检查这个类是否被映射并采取相应的行动。

作为一种解决方法,您可以尝试在映射中映射 EdmMetadata 实体(而不是为此使用此约定,因此请保留该约定),您可以在其中使用适当的大小或类型(文本)显式映射 ModelHash 属性.关于“如何映射字段长度或字段类型”,您可以在此处找到信息:How do I specify that a property should generate a TEXT column rather than an nvarchar(4000) 根据那里的答案,这应该将列的类型更改为文本:

modelBuilder.Entity<EdmMetadata>()
.Property(e => e.ModelHash)
.HasColumnType("text");

有人可以试试这种方法吗?

【讨论】:

以上是关于带有 MySQL 连接器 6.4.3 的实体框架 4 自动生成表导致“列长度”异常的主要内容,如果未能解决你的问题,请参考以下文章

带有 MySQL 的实体框架

带有 Mysql 和 NullReferenceException 的实体框架 6

实体框架4 unicode问题保存

VS 2010 - 带有 MySql 存储过程的实体框架似乎不起作用

无法将 MySQL 连接用于实体框架 6

“提供者没有返回 ProviderManifestToken 字符串”带有实体框架的 MySQL