我有一个带有数据库第一种方法和SQL Server数据库的项目。
在其中一个表中,我有一个不可为空的列,其默认值为空字符串:
[Comments] NVARCHAR(1024) NOT NULL DEFAULT ('')
这里的默认值应该始终是一个空字符串,以完全支持odata“Is not empty”过滤器,否则返回带有空值的记录,这些值从业务角度来看确实是空的。
在我的模型中,我还有一个字符串属性:
public string Comments { get; set; }
现在发生的事情是:从前端我可能得到空值,如果适当的输入没有填充数据,这个值将映射到实体,然后由EF插入。
如果我只是尝试使用null“Comments”属性设置记录而不是在SQL端获取默认值,那么我将获得异常。
我尝试通过在EDMX中将此列的StoreGeneratedPattern
设置为Computed
来解决此问题。现在我可以插入带有空值的记录,并且我得到默认值,但我每次都得到它,即使在实体中有值。
换句话说,计算StoreGeneratedPattern
总是忽略实体中此属性的值,禁用StoreGeneratedPattern
基本上让我在SQL端没有默认值。
我想要的是以一种不错的方式在后端解决这个问题。
我不想通过总是从前端发送空字符串并向后端添加验证来解决此问题,即此属性永远不会为null。它会迫使我为其他客户(例如移动客户端)以及我遇到相同情况的每个表格和表格做同样的事情。
我不想通过以下方式来解决它:
entity.Comments = entity.Comments ?? string.empty;
在后端。它将迫使我在处理此实体和其他类似实体的每个地方都这样做。
我不想通过使用类似实体的某个接口或在构造函数中初始化此属性来解决它。我有一个单独的T4模板,它可以从EDMX为我构建实体模型,用于解耦原因,因此所有模型都是自动生成的,不应该自定义。
我期待的行为以及我想达到的行为如下:
如果EF尝试为此列插入一个空值的记录,SQL Server将使用DEFAULT,否则它会插入实体所拥有的内容。
非常感谢任何想法或解决方案。
答案 0 :(得分:0)
我有一个泛型函数,我在CRUD函数中用于此类任务
__builtin_frame_address()
只需在插入之前调用它,如
private T SetNullStringToDefault<T>(T entity, string default)
{
List<PropertyInfo> properties = entity.GetType().GetProperties().ToList();
foreach(var property in properties)
{
//if property is string
if(property.PropertyType == typeof(string))
{
string value = property.GetValue(entity, null) as string;
if (string.IsNullOrEmpty(value))
property.SetValue(entity, default, null);
}
}
return entity;
}
只需将对象传递给它,它就会将所有NULL字符串属性转换为默认值。