簡體   English   中英

使用自定義ValueConverter時Select上的System.InvalidCastException

[英]System.InvalidCastException on Select when using custom ValueConverter

問題

我正在嘗試在我的一個實體中引入強類型ID。 為此,我遵循了https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-3/上的說明

與上述說明的唯一區別是,我試圖將ID保留為字符串而不是Guid。

說明的簡短摘要(可在此處下載完整示例: https : //drive.google.com/file/d/1_mtYp1c8W6qJoEAY-8NPNjYvsSAif4mz/view?usp=sharing ):

  • 創建具有屬性“ Value”的結構“ OrderId”,該結構返回ID的字符串表示形式
  • 為Order實體創建類,並添加類型為“ OrderId”的屬性“ ID”
  • 使用DbSet創建DbContext
  • 創建一個自定義ValueConverter,將OrderId轉換為字符串,反之亦然
  • 將值轉換器應用於Order實體的Id列
  • 為了避免客戶端評估,將一個從OrderId到字符串的顯式轉換運算符添加到OrderId中

使用此設置,將條目添加到“訂單”表中沒問題。 但是:當我嘗試閱讀它們時,會引發以下異常:

System.InvalidCastException
  HResult=0x80004002
  Message=Invalid cast from 'System.String' to 'StronglyTypedIds.OrderId'.
  Source=System.Private.CoreLib
  StackTrace:
   at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) in E:\A\_work\644\s\src\mscorlib\shared\System\Convert.cs:line 309
   at Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter`2.Sanitize[T](Object value) in /_/src/EFCore/Storage/ValueConversion/ValueConverter`.cs:line 52
   at Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter`2.<>c__DisplayClass3_0`2.<SanitizeConverter>b__0(Object v) in /_/src/EFCore/Storage/ValueConversion/ValueConverter`.cs:line 43
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapping.CreateParameter(DbCommand command, String name, Object value, Nullable`1 nullable) in /_/src/EFCore.Relational/Storage/RelationalTypeMapping.cs:line 515
   at Microsoft.EntityFrameworkCore.Storage.Internal.TypeMappedRelationalParameter.AddDbParameter(DbCommand command, Object value) in /_/src/EFCore.Relational/Storage/Internal/TypeMappedRelationalParameter.cs:line 66
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalParameterBase.AddDbParameter(DbCommand command, IReadOnlyDictionary`2 parameterValues) in /_/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs:line 45
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.CreateCommand(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues) in /_/src/EFCore.Relational/Storage/Internal/RelationalCommand.cs:line 375
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues) in /_/src/EFCore.Relational/Storage/Internal/RelationalCommand.cs:line 149
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues) in /_/src/EFCore.Relational/Storage/Internal/RelationalCommand.cs:line 119
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer) in /_/src/EFCore.Relational/Query/Internal/QueryingEnumerable.cs:line 111
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext() in /_/src/EFCore.Relational/Query/Internal/QueryingEnumerable.cs:line 93
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) in E:\A\_work\286\s\corefx\src\System.Linq\src\System\Linq\First.cs:line 63
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable`1.GetEnumerator() in /_/src/EFCore/Query/Internal/LinqOperatorProvider.cs:line 294
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17`2.MoveNext() in /_/src/EFCore/Query/Internal/LinqOperatorProvider.cs:line 185
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext() in /_/src/EFCore/Query/Internal/LinqOperatorProvider.cs:line 143
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) in E:\A\_work\286\s\corefx\src\System.Linq\src\System\Linq\First.cs:line 63
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) in E:\A\_work\286\s\corefx\src\System.Linq\src\System\Linq\First.cs:line 14
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_1`1.<CompileQueryCore>b__0(QueryContext qc) in /_/src/EFCore/Query/Internal/QueryCompiler.cs:line 132
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) in E:\A\_work\286\s\corefx\src\System.Linq.Queryable\src\System\Linq\Queryable.cs:line 741
   at StronglyTypedIds.Program.Main() in <path_to_project>\StronglyTypedIds\StronglyTypedIds\Program.cs:line 29

奇怪的是,這似乎取決於我如何構建Where-query:

var order = dbContext.Orders.Where(o => (string)o.Id == "1").ToList();                             // works


const string idAsStringConstant = "1";
order = dbContext.Orders.Where(o => (string)o.Id == idAsStringConstant).ToList();                  // works


var idAsStringVariable = "1";
order = dbContext.Orders.Where(o => (string)o.Id == idAsStringVariable).ToList();                  // doesn't work


order = dbContext.Orders.Where(o => (string)o.Id == OrderId.Parse("1").StringValue).ToList();      // doesn't work

重現步驟

這是一個帶有示例的VS2019小型解決方案: https ://drive.google.com/file/d/1_mtYp1c8W6qJoEAY-8NPNjYvsSAif4mz/view?usp=sharing

更多技術細節

EF Core版本:2.2.6數據庫提供程序:Microsoft.EntityFrameworkCore.SqlServer和Microsoft.EntityFrameworkCore.Sqlite操作系統:Windows 10 1809 IDE:(例如Visual Studio 2019 16.1.6)

好的,這是實體框架中的錯誤。 如果我安裝了.NET Core和Entity Framework Core 3.0版的預覽版,則它將按預期工作。 此外,似乎還有一個針對2.2版的修復程序,該修復程序尚未發布(請參閱https://github.com/aspnet/EntityFrameworkCore/issues/17610 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM