【问题标题】:How do you properly handle SQL_VARIANT in Entity Framework Core?您如何正确处理 Entity Framework Core 中的 SQL_VARIANT?
【发布时间】:2018-04-06 23:15:07
【问题描述】:

似乎最近在 .NET Core 2.1 (preview) 中向 Entity Framework Core 添加了支持,以允许映射 SQL_VARIANT 列 (https://github.com/aspnet/EntityFrameworkCore/issues/7043)。

看起来这样做的方法是使用新的HasConversion() 方法 (https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions)。

所以,为了映射我的SQL_VARIANT 列并将底层数据类型视为任意长度的VARCHAR(我现在只关心阅读它),我可以执行以下操作(其中@987654328这里的@属性是模型中的object类型):

entity.Property(e => e.Value).HasConversion(v => v.ToString(),
                                                            v => v.ToString());

如果SQL_VARIANT 的基础数据类型是任意长度的VARCHAR,则此方法有效。

但是,作为SQL_VARIANT,该列可以包含其他类型的数据,例如DATETIME 值。

为简单起见,我在这里只指定了DateTimestring,但理论上我可能希望支持映射任何可能存储在SQL_VARIANT 列中的数据所需的数据类型,如果可能的话。

我将如何确定我想在运行时映射到这两种类型(stringDateTime)中的哪一种?有没有办法做到这一点?

【问题讨论】:

  • 您不需要使用任何转换。只需将模型中object 类型的属性映射到数据库中sql_variant 类型的列,仅此而已。然后,如果您阅读列并且它是 sql 日期时间 - 您的 object 模型属性将是 System.DateTime 类型。如果它在 sql server 端是十进制 - 在 .NET 中它将是 System.Decimal,依此类推。
  • 这听起来确实是理想的场景(以及我认为的开始方式),但是在生成模型时,未检测到 SQL_VARIANT 列,所以我不得不手动添加它到模型(类型为object),也到OnModelCreating(),使用entity.Property(e => e.Value);。不幸的是,这不起作用,并抛出 InvalidOperationException 和消息 'No mapping to a relational type can be found for the CLR type 'object'.
  • 我对其进行了测试,它对我有用(最后一个 EF 2.1 预览版)。我是这样做的:.Property(e => e.Value).HasColumnType("sql_variant");。也许你没有添加HasColumnType
  • @Evk 我认为您应该从您的 cmets 中撰写答案。可能稍后会更新提供程序以自动设置列类型,但现在这应该是要走的路。
  • @Evk 哇,成功了!你能把它作为你的答案并解释为什么会这样吗?我在哪里可以阅读更多关于此的内容?我承认我对实体框架相当陌生。 EF Core 是我第一次涉足这一切。我没有意识到我必须手动告诉它列类型是什么,因为我认为它是自动检测到的。

标签: c# .net-core entity-framework-core sql-variant


【解决方案1】:

据我了解,目前的方法是:

// where e.Value is property of type "object"
entity.Property(e => e.Value).HasColumnType("sql_variant");

仅此而已,无需任何自定义转换器。正如pull 添加此功能的消息所述:

类型映射器现在会将属性映射到 sql_variant 列,如果:

  • 属性为对象类型
  • 存储类型名称指定为 sql_variant

您当前的代码满足第一个条件(属性类型为object),但不满足第二个条件。为什么它不能从对象类型的属性推断存储类型名称 - 我不太确定,可能只是因为实体框架不是特定于 sql-server 并且支持许多其他数据库,其中object 属性可以具有不同的语义或完全不支持,因此需要明确说明您的意图。

【讨论】:

  • 您知道是否有任何可用于 Entity Framework Core 的优秀文档说明 HasColumnType() 在哪里需要和不需要?我注意到,对于它生成的DbContext 文件,一些字段(如DateTime 列)已通过HasColumnType() 调用自动创建,但其他字段(如string 的)没有。
  • @Interminable 我能找到的只有这个链接:docs.microsoft.com/en-us/ef/core/modeling/relational/data-types。它基本上说“数据库提供者根据属性的 CLR 类型选择数据类型”,因此由提供者决定如何映射给定的属性。因此,当从数据库生成 dbcontext 时 - 我猜提供程序使用显式 HasColumnType ,其中实际列类型与默认情况下使用的不匹配(例如默认情况下 DateTime 它将使用 datetime2(7),但您在数据库中的列是说smalldatetime),否则将忽略该调用。
猜你喜欢
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
  • 2019-12-15
  • 1970-01-01
相关资源
最近更新 更多