在类型'System.Int16'和'System.Boolean'

时间:2018-12-12 12:29:17

标签: c# mysql asp.net entity-framework lambda

我正在使用一个帮助器类来构建一个表达式,然后将该表达式传递给EF Core .Select()上的DbSet调用,以便我可以从数据库中动态选择字段并忽略大字段我不在乎的。

助手类如下:

public static class ExpressionHelper
{
    public static Expression<Func<T, T>> BuildFieldSelector<T>(IEnumerable<string> fields)
    {
        // input parameter "x"
        var param = Expression.Parameter(typeof(T), "x");

        // new statement "new Data()"
        var newExpression = Expression.New(typeof(T));

        // create initializers
        var bindings = fields
            .Select(x => {
                // property "Field1"
                var property = typeof(T).GetProperty(x.Trim(), BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

                if (property == null)
                    return null;

                // original value "x.Field1"
                var memberExpression = Expression.Property(param, property);

                // set value "Field1 = x.Field1"
                return Expression.Bind(property, memberExpression);
            })
            .Where(x => x != null);

        // initialization "new Data { Field1 = x.Field1, Field2 = x.Field2 }"
        var memberInit = Expression.MemberInit(newExpression, bindings);

        // expression "x => new Data { Field1 = x.Field1, Field2 = x.Field2 }"
        return Expression.Lambda<Func<T, T>>(memberInit, param);
    }
}

正如我所说的,生成的表达式被传递给EF DbSet上的.Select() LINQ调用。

一切正常,但我现在遇到以下异常:

No coercion operator is defined between types 'System.Int16' and 'System.Boolean'.
   at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
   at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method)
   at System.Linq.Expressions.Expression.Convert(Expression expression, Type type)
   at Microsoft.EntityFrameworkCore.Storage.TypedRelationalValueBufferFactoryFactory.CreateGetValueExpression(Expression dataReaderExpression, Expression indexExpression, TypeMaterializationInfo materializationInfo, Boolean box)
   at Microsoft.EntityFrameworkCore.Storage.TypedRelationalValueBufferFactoryFactory.<>c.<CreateArrayInitializer>b__12_0(TypeMaterializationInfo mi, Int32 i)
   at System.Linq.Enumerable.SelectIterator[TSource,TResult](IEnumerable`1 source, Func`3 selector)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable`1 enumerable)
   at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable`1 initializers)
   at Microsoft.EntityFrameworkCore.Storage.TypedRelationalValueBufferFactoryFactory.CreateArrayInitializer(CacheKey cacheKey)
   at Microsoft.EntityFrameworkCore.Storage.TypedRelationalValueBufferFactoryFactory.<Create>b__10_0(CacheKey k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Storage.TypedRelationalValueBufferFactoryFactory.Create(IReadOnlyList`1 types)
   at Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.CreateValueBufferFactory(IRelationalValueBufferFactoryFactory relationalValueBufferFactoryFactory, DbDataReader dataReader)
   at Microsoft.EntityFrameworkCore.Query.Internal.ShaperCommandContext.<NotifyReaderCreated>b__14_0(FactoryAndReader s)
   at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Query.Internal.ShaperCommandContext.NotifyReaderCreated(DbDataReader dataReader)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at TAP.Services.TourManagementService.GetReviews(String tourId, IEnumerable`1 fields) in C:\Projects\TheAdventurePeople\TAP.Services\TAP.Services\Services\TourManagementService.cs:line 322

自从工作以来,我根本没有更改过代码,因此我不确定是什么原因造成的。我也没有更改用于表达式的模型类中的任何类型。在此实例中正在构建的表达式如下所示:

{x => new TourReview() {ReviewId = x.ReviewId, TourId = x.TourId, Score = x.Score, ReviewerName = x.ReviewerName, IsHidden = x.IsHidden}}

和TourReview类如下:

public class TourReview
{
    public int ReviewId { get; set; }
    [Required]
    public string TourId { get; set; }
    [Required]
    [DataType(DataType.Date)]
    [Display(Name = "Review Date")]
    public DateTime DateReviewed { get; set; }
    [Required]
    public decimal Score { get; set; }
    public string Title { get; set; }
    [Required]
    [Display(Name = "Review Text")]
    public string Text { get; set; }
    [Required]
    [Display(Name = "Reviewer Name")]
    public string ReviewerName { get; set; }
    public bool IsHidden { get; set; }
}

我最近确实从5.7升级到了.NET Core 2.1和MySQL 8.0.13,

编辑: 我还记得最近我已经从Pomelo MySQL连接器更改为官方的MySQL.Data.EntityFrameworkCore连接器。

编辑2: 我相信这是在我对本地计算机上的MySQL Server进行升级之后开始发生的。新版本似乎导致类型映射出现问题。将.Property(x => x.IsHidden).HasConversion(x => Convert.ToInt32(x), x => Convert.ToBoolean(x));添加到模型构建器可以解决此问题,但我不想对我拥有的每个布尔属性都执行此操作!

0 个答案:

没有答案