2

在 2 个不同的 MySql 安装上使用相同的 MVC 3 和 C# 代码以及相同 MySql 5.5 数据库的副本时。一个工作完美,而另一个失败并出现“对象必须实现 IConvertible”错误。当我对本地 PC 的 MySql 安装运行查询时,查询始终运行良好,但是当我尝试从本地 PC 的 Visual Studio 2010 查询到我的 Internet 服务提供商的 MySql 安装的同一数据库的副本时,我收到错误“对象必须实施 IConvertible”。我在代码中唯一更改的是 web.config 中的 ConnectionString 的服务器名称,否则代码和数据库完全相同。注意:对 ISP 的 MySql 安装的所有其他查询都可以正常工作,只有这个特定的查询不起作用。

在尝试解决此问题几天后,我确信错误消息“对象必须实现 IConvertible”与实际发生的事情无关,而且我还认为我的 ISP 上的 MySql 配置可能以某种方式导致这个问题的原因如下:

  1. 如果这确实是代码中的“对象必须实现 IConvertible”问题,那么无论我安装哪个数据库,该问题都会持续存在于代码中。

  2. 我已经完全从本地 PC 的工作副本中删除并在 ISP 处重新创建了数据库,但仍然收到完全相同的错误。

  3. 最有趣的是,该查询有 3 个嵌套的 IEnumerable 列表,它们的设置方式与 IEnumerables 相同,如果我在查询中注释掉这些嵌套列表中的任何 1 个,则查询会针对 ISP 的数据库成功运行。哪个嵌套列表被注释掉并不重要,只要有 2 个或更少的嵌套列表,然后对 ISP 的数据库的查询就可以工作。这就是让我得出结论,MySql 在 ISP 的配置可能会以某种方式限制我的查询,因为在查询本地 PC 的 MySql 安装时我没有这个问题。错误消息似乎并不适用于实际发生的事情。同样,对 ISP 的 MySql 安装的所有其他查询都可以正常工作,但是它们都不包含超过 2 个嵌套的 IEnumerable 列表,其中这个特定查询包含 3 个?

查询错误“对象必须实现 IConvertible”

    Server Error in '/' Application.
    ________________________________________
    Object must implement IConvertible. 
    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: System.InvalidCastException: Object must implement IConvertible.

    Source Error: 

    Line 392:
    Line 393:
    Line 394:            var query =
    Line 395:                  (from p in db.products
    Line 396:                   where p.ClientId == clientId

    Source File: C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs    Line: 394 

    Stack Trace: 

    [InvalidCastException: Object must implement IConvertible.]
    System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +9528453
    MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue, Type targetType) +566
    MySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 ordinal) +231
    System.Data.Common.Internal.Materialization.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal) +215
    System.Data.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling(Int32 ordinal) +46
    lambda_method(Closure , Shaper ) +180
    System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) +170
    System.Data.Common.Internal.Materialization.RowNestedResultEnumerator.MoveNext() +235
    System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.TryReadToNextElement() +49
    System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.ReadElement() +29
    System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.MoveNext() +68
    System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +327
    System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
    ReservarMVC.Models.ProductRepository.GetProductList(Nullable`1 dateStart, Nullable`1    dateEnd,         Nullable`1 personQuantityId, Nullable`1 roomQuantityId) in C:\Users\JR\Documents     \Visual      Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs:394
    ReservarMVC.Models.ProductRepository.GetProductListSearch(Nullable`1 dateStart, Nullable`1 dateEnd, Nullable`1 personQuantityId, Nullable`1 roomQuantityId) in C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs:605
    ReservarMVC.Controllers.PortalController.MyExcurcion(ProductListSearchVM viewModel) in C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Controllers\PortalController.cs:63
     lambda_method(Closure , ControllerBase , Object[] ) +162
     System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
     System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
      System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
      System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
      System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
      System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
      System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 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__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
      System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
      System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
      System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>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() +8967601
      System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

      ________________________________________
      Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.261

LINQ 到实体查询:

    public IEnumerable<ProductListVM> GetProductList(DateTime? dateStart, DateTime? dateEnd, int? personQuantityId, int? roomQuantityId)
    {
        var query =
              (from p in db.products
               where p.ClientId == clientId
               where p.ProductTypeId == 5 
               where personQuantityId <= p.Capacity
               where roomQuantityId <= p.Quantity
               select new ProductListVM
               {
                   ProductId = p.ProductId,
                   ClientId = p.ClientId,
                   Name = p.Name_en,
                   Title = p.Title_en,
                   Description = p.Description_en,
                   Quantity = p.Quantity,
                   Capacity = p.Capacity,
                   newbookings = from b in db.bookings 
                                 where b.ProductId == p.ProductId
                                 from res in db.reservations
                                 where b.ReseravationId == res.ReservationId
                                 where b.BookingDateTime >= dateStart && b.BookingDateTime <= dateEnd && res.ReservationStateId != 3 
                                 select new BookingVM
                                 {
                                     ProductId = b.ProductId,
                                     BookingId = b.BookingId,
                                     ClientId = b.ClientId,
                                     ReservationId = b.ReseravationId,
                                     BookingDateTime = b.BookingDateTime
                                 },                  
                   newratecategories = from prc in db.productratecategories
                                       where prc.ProductId == p.ProductId
                                       from rc in db.ratecategories
                                       where prc.RateCategoryId == rc.RateCategoryId
                                       where (dateStart >= rc.DateStart && dateEnd <= rc.DateEnd) || (dateStart >= rc.DateStart || dateEnd <= rc.DateEnd)                                           
                                       select new MegaRateCategoryVM
                                       {
                                           RateCategoryId = rc.RateCategoryId,                                               
                                           DateStart = rc.DateStart,
                                           DateEnd = rc.DateEnd                                      
                                       },
                   newproductimages = (from pi in db.productimages
                                       where pi.ProductId == p.ProductId
                                       from ig in db.imagegalleries
                                       where pi.ImageGalleryId == ig.ImageGalleryId
                                       select new MegaProductImageVM
                                       {
                                           ig_Description = ig.ig_Description,
                                           ImageGalleryId = pi.ImageGalleryId
                                       }).OrderByDescending(i => i.ImageGalleryId)
               }).ToList();

        return query;
    }

产品列表视图型号:

    namespace Project.ViewModels
    {
        [Serializable]
        public class ProductListVM : BaseViewModel
        {        
            public int ProductId { get; set; }        
            public int? ClientId { get; set; }
            public int? ProductTypeId { get; set; }
            public int? ProductStateId { get; set; }
            public String Name { get; set; }        
            public String Title { get; set; }
            public String Description { get; set; }
            public int? Quantity { get; set; }
            public int? Capacity { get; set; }        

            //PRODUCTIMAGE table fields
            public IEnumerable<MegaProductImageVM> newproductimages { get; set; }

            //RATECATEGORY table fields
            public IEnumerable<MegaRateCategoryVM> newratecategories { get; set; }

            //BOOKING table fields
            public IEnumerable<BookingVM> newbookings { get; set; }       

        }

    }

什么可能导致这种行为?这可能是由 MySql 5.5 的数据库配置上的查询阈值设置或网络设置引起的吗?我没有更改任何一个 MySql 5.5 安装的任何默认值。我只是使用标准的 MySql Connector/Net 6.5.4 以及 Microsoft 的标准 MVC 3、C#、Entity Framework 4、LINQ-to-Entities 代码来访问数据库。

非常感谢您对此的任何帮助。谢谢, Atlas361

4

2 回答 2

7

要解决此问题,请在连接字符串中添加“尊重二进制标志 = false”,例如:

connectionString="metadata=res://*/Something.csdl|res://*/Something.ssdl|
res://*/Something.msl;provider=MySql.Data.MySqlClient;
provider connection string=&quot;server=my-server;User Id=some-user;
Persist Security Info=True;database=some-database;respect binary flags=false&quot;"

这是某些版本的 MySQL 5.0 和 5.1的已知问题

在某些情况下,MySQL 会返回关于一列或多列的不正确元数据...如果您的应用程序所需的更改太大,将“尊重二进制标志=false”添加到您的连接字符串会导致连接器使用先前的行为:任何标记为字符串的列,无论二进制标志如何,都将作为字符串返回。只有特别标记为 BLOB 的列才会作为 BLOB 返回。

希望这对未来的旅行者有所帮助。

于 2013-04-11T22:55:25.450 回答
0

我向 ISP 发布了我的 MVC 应用程序,以便消除通过 Internet 查询引起的任何潜在问题,但我仍然遇到同样的错误“对象必须实现 IConvertible”。在 Arvixe.com 完全无能的支持人员进一步排除故障后我发现他们拥有数据库的 MySql 的实际版本是 2008 年发布的 5.1.54,而不是 2010 年底发布的 MySql 5.5。根据 MySql 文档,MySql Connector/Net 6.5.4 和 Microsoft 的 Entity Framework 4 是兼容的,但我发现这不是真的。在与 Arvixe.com 争吵后将我放在 MySql 5.5 服务器上,问题就消失了。所以最后这是版本兼容性问题。

希望答案有帮助!阿特拉斯361

于 2013-01-22T03:19:43.047 回答