【问题标题】:Entity Framework Code First - DbNull Convention实体框架代码优先 - DbNull 约定
【发布时间】:2023-03-12 12:20:01
【问题描述】:

我的问题是我有一个无法修改的现有表,其中包含可为空的字段。

我有一个模型,我不想要可以为空的属性。

我想要做的是有一个约定(我想是这样),当从数据库中遇到 DBNull 时,我可以根据模型属性类型设置 默认值 使用。

  • ints/double = 0
  • 字符串 = ""
  • bool = 假

很确定这在 NHibernate 中很简单,但我不知道如何在 EF 中执行此操作。

我正在使用来自 nuget 的最新 EF 包,我认为它是 EF 4.2。

【问题讨论】:

  • 您为什么不希望 DBMS 为您管理这个?这似乎是您想要集中管理的东西。
  • 具有公制垃圾负载的旧系统。更改表架构可能会影响我无法处理的某处的某些内容。使我的模型可以为空以匹配数据库是最后的选择。我相信当 EF 从数据库绑定到模型时,应该可以在某处引入检查约定。
  • 我想知道你为什么不想要可为空的属性。 Nullable 就是为这种情况而设计的。
  • @allentranks - 我不认为 Nullable<T> 可以原生处理 DBNull,你确定它适用吗?

标签: c# .net entity-framework-4.1


【解决方案1】:

这是不可能的,因为 EF 不支持自定义约定(除非您修改它们)。此外,即使有约定,它也可能行不通。

您正在寻找的是自定义简单类型映射(或简单类型转换)。这是 ORM 的一个非常重要的特性,但到目前为止它在 EF 中完全被忽略了。目前 DB 类型应该与您在 EF 模型中的类型匹配,否则您可能会遇到严重的问题,因为您无法在映射中进行任何转换。 EF 5 将支持第一次转换,它只支持将 int 转换为 enum(硬编码转换)。

在数据库中的 EF 可空类型 => 模型中的可空类型。

【讨论】:

  • 这基本上是我需要但不想听到的答案。谢谢拉迪斯拉夫。
【解决方案2】:

正如 alentranks 在上面所暗示的,这可以通过 Nullable<T> 属性使用一些魔法来处理。根据我的经验,Nullable<T> 不能自己处理DBNull(尽管我可能是错的),你可以使用定义here 的技巧:

private static T NullValue<T>( object testValue, T nullValue )
{
    T returnValue;
    if( testValue is DBNull )
    {
        returnValue = nullValue;
    }
    else if( typeof(T).GetGenericTypeDefinition().Equals( typeof(Nullable<>) ) )
    {
        returnValue = (T)Convert.ChangeType( testValue, Nullable.GetUnderlyingType( typeof(T) ) );
    }
    else
    {
        returnValue = (T)Convert.ChangeType( testValue, typeof(T) );
    }

    return returnValue;
}

【讨论】:

  • 谢谢你,但这不是我想要的。我知道我的模型可以处理 Null 类型。我试图探索的选项是通过约定自动转换这些 DBNulls。在 NHibernate 中,我相信您实现了 IPropertyConvention 并且可以在那里进行检查。我正在追逐一个等效的 EF。
  • 或许the answer to this question 会更合适。
猜你喜欢
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多