实体框架代码优先 - 不可为空类型的默认值

Posted

技术标签:

【中文标题】实体框架代码优先 - 不可为空类型的默认值【英文标题】:Entity Framework Code First - Default values on non-nullable types 【发布时间】:2011-10-29 20:28:13 【问题描述】:

我正在尝试使用旧版 POCO 模型映射旧版数据库。由于开发的数据库和模型没有考虑实体框架,因此它们之间的一些细微差别让我卡住了。

我面临的挑战是,我想让它的工作侵入性尽可能低(不想接触数据库或模型的代码),因为依赖的代码太多。

我尝试使用代码优先方法映射实体,重用旧模型中的 POCO。因为我发现一些可以为空的数字列被映射到声明为原始 Int32(不可为空)的属性,所以一切似乎都可以找到。

例如,假设我有一张桌子:

CREATE TABLE [dbo].[SomeTable](
    [Id] [int] NOT NULL,
    [Descrip] [nvarchar](50) NULL,
    [SomeNumericCol] [int] NULL,
 CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)) ON [PRIMARY]

以及对应的POCO:

public class SomeTable

    public Int32 Id  get; set; 
    public string Descrip  get; set; 
    public Int32 SomeNullableCol  get; set; 

正如您可能看到的,列 SomeNullableCol 和相应的属性之间存在差异,因为最后一个的类型是不允许空值的原始 int。

是否有一个技巧可以使这个映射工作,而不必将 SomeNullableCol 的类型更改为可为空的 int(我的意思是 Int32?),并且如果可能的话,不要触及类的代码。

谢谢!

【问题讨论】:

【参考方案1】:

是的,只需用数据注释来掩盖它。创建一个可为空的 int 并将其屏蔽为列名,然后创建一个具有相同名称的非映射属性,该属性仅从可为空的列返回一个 int 值。

        [Column("SomeNullableCol")]
        public int? TestValue  get; set; 

        [NotMapped]
        public int SomeNullableCol
        
            set  TestValue = value; 
            get
            
                if (TestValue != null) return (int) TestValue;
                return -1;
            
        

【讨论】:

这将解决部分问题,因为我不想触及 POCO 定义。尽管如此,它给了我下一个想法:从 POCO 继承并在那里添加“代理”属性。我会尝试通过反思来做到这一点...... 这个 hack 至少维护了 POCO 的当前结构,因此在根据您的要求增强它的同时不会破坏遗留代码。另一种选择是使用中间人。创建一个与旧数据库匹配的新 POCO,然后将旧 POCO 映射到新 POCO,而不是映射到数据库。 是的。正如我所说,您的回答让我想到了动态构建具有可为空属性的类型(使用 Reflection.Emit)。然后我可以将生成的类型映射到数据库。谢谢。 属性不能在LINQ中使用,所以不能翻译成sql会出现异常【参考方案2】:

你能让你的 POCO 上的属性为空吗?

public class SomeTable

    public Int32 Id  get; set; 
    public string Descrip  get; set; 
    public Int32? SomeNumericCol  get; set; 

【讨论】:

不,我不能 :-( 。正如我所说,我不能将它更改为可空类型,因为有太多代码依赖于这些属性是 int。Ant 有很多属性也会改变...

以上是关于实体框架代码优先 - 不可为空类型的默认值的主要内容,如果未能解决你的问题,请参考以下文章

EF 6.X 中的实体框架代码优先 Fluent API 默认值

在实体框架数据库优先方法中将默认值 1 设置为实体名称(状态)

实体框架的 SQL 列默认值

实体框架支持来自数据库优先方法的默认约束

如何在实体框架中创建只读实体?

实体框架:值不能为空。参数名称:类型