【问题标题】:Is there a way to force EF Core to ignore SQL datatypes有没有办法强制 EF Core 忽略 SQL 数据类型
【发布时间】:2017-11-23 08:22:49
【问题描述】:

如何强制 EF Core 为单个属性处理多种 sql 数据类型?目标是处理处理相同类型但不统一的多个客户端数据库。

采取以下措施,这似乎仅在客户端数据库具有十进制兼容数据类型时才有效。

    Public Property PieceThickness As Decimal
    Get
        PieceThickness = _pieceThickness
    End Get
    Set(value As Decimal)
        _pieceThickness = value
    End Set
End Property

但有些客户端会将 PieceThickness 设为 varchar(9)。因此即使我手动映射列也会引发错误。

modelBuilder.Entity(Of MailPiece)().Property(Function(t) t.PieceThickness).
         HasColumnName("Thickness").HasColumnType("varchar(9)")

“读取属性‘MailPiece.PieceThickness’的数据库值时发生异常。预期类型为‘System.Nullable`1[System.Decimal]’,但实际值为‘System.String’类型。”

我显然可以为 PieceThickness 设置另一个字符串属性,但如果可能的话,我想避免这种情况。使属性成为对象也不起作用。

我了解模型需要与数据库完全匹配,但我希望有一个解决方法。

编辑:我认为处理这种情况的最佳选择是使用工厂模式或提供者工厂:http://www.dofactory.com/net/design-patterns

这样做,我将拥有一个可扩展的解决方案,该解决方案可以逐个客户偏离标准。

【问题讨论】:

标签: sql vb.net orm entity-framework-core


【解决方案1】:

我能想到的唯一解决方法是将您从数据库中读取的任何内容转换为 Decimal 或其他数字类型,并希望那里的数据有效。例如,您可以使用一个视图并从中读取,它的一部分将被定义为

SELECT CAST(PieceThickness AS numeric(18,0)) PieceThickness FROM YourTable

在其他领域。然后从视图而不是表中运行 LINQ 查询。然后,您可以为您的字段选择可以在各种数据库系统中找到的类型。

更新

鉴于您可能想要执行 crud 操作,我可能会建议另一种不太优雅的解决方法。我有一个无法在其上创建存储过程和/或视图的数据库。它有一些 Unix Timestamp 格式的日期,但我需要在我的代码中使用实际日期。我使用的解决方法是这样的......

Public Class Demo
    Public Property GpsTime As Integer

    Public Readonly Property AssembledTime As Date
        Get
            Return GpsTime.FromUnixTimestamp()
        End Get
    End Property
End Class

FromUnixTimestamp() 是我必须翻译的扩展方法。如果您确实找不到除 varchar 之外的常见类型,则可以将其作为 varchar 存储在数据库中,并使用类似这样的方法来处理它,该方法可以在保存之前写回字符串属性。您只需确保 EF Core 忽略 Decimal 属性。

在您的情况下,您将需要如下代码:

Public Property PieceThickness As String

Public Property PieceThicknessD As Decimal
    Get
        Dim workingValue As Decimal
        If Decimal.TryParse(PieceThickness, workingValue) Then Return workingValue
    End Get
    Set(value as Decimal)
        PieceThickness = value.ToString()
    End Set
End Property

这就是我想到的解决方法。虽然我仍然认为您应该能够获得各种数据库系统共有的数据类型。

【讨论】:

  • 映射到视图是否允许正常的 CRUD 操作?
  • 该解决方法是用于读取数据。我没有使用具有可更新视图的 ORM 解决方案,因此我无法准确回答该问题。如果你愿意,你可以用存储过程来做你的事情。或者更确切地说,使用您知道所有目标平台都可以处理的十进制以外的数据类型
  • 我已经更新了我的答案,@DavidTheDev 检查它现在是否适合你
  • 帮助我理解这一点,使用上述逻辑,我需要让目标数据库具有统一的思维数据类型 varchar,然后调用 Conver.ToDecimal。
  • 您是先使用数据库还是先使用代码?为什么我要问的是您可能要考虑使用 Double 而不是 Decimal。我知道的所有 DBMS 都有一些可以与 double 配合使用的东西,这样,您可以让 EF 弄清楚如何将数据从 DB 转换为运行时对象。查看此链接w3schools.com/Sql/sql_datatypes_general.asp 了解更多信息。您还希望研究提供者模式以设计您的 DAL,以便您可以根据您的目标平台将其换出,而大部分代码保持不变
猜你喜欢
  • 2017-03-17
  • 2010-11-17
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多