【发布时间】: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 值。
为简单起见,我在这里只指定了DateTime 和string,但理论上我可能希望支持映射任何可能存储在SQL_VARIANT 列中的数据所需的数据类型,如果可能的话。
我将如何确定我想在运行时映射到这两种类型(string 和 DateTime)中的哪一种?有没有办法做到这一点?
【问题讨论】:
-
您不需要使用任何转换。只需将模型中
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