有没有办法强制EF Core忽略SQL数据类型

时间:2017-06-20 16:57:45

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

如何强制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

这样做我将拥有一个可扩展的解决方案,可以在客户端基础上偏离规范。

1 个答案:

答案 0 :(得分:0)

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

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

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

<强>更新

看到你可能想要执行crud操作,我可能会建议另一种不太优雅的解决方法。我有一个我使用的数据库,我无法创建sprocs和/或视图。它有一些Unix时间戳格式的日期,但我需要在我的代码中使用实际日期。我使用的解决方法就是这样......

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

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