【发布时间】:2019-12-19 23:46:29
【问题描述】:
我在数据库表中添加了一列,该列是根据其他列的值计算得出的。它从不直接设置,而是在更新这些列时更新。
我已经在我的模型类中实现了这一点,没有任何原始 SQL,它可以很好地解决一个问题:我希望迁移在应用时为所有行填充此列,而不必等待手动更新每个字段改变之后。
模型的简化示例如下:
public class MyModel
{
private string _title;
private string _description;
private string _data;
public string Title
{
get
{
return _title;
}
set
{
_title = value;
UpdateCombinedField(value, _description, _data);
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
UpdateCombinedField(_title, value, _data);
}
}
[Column(TypeName = "jsonb")]
public string Data
{
get
{
return _data;
}
set
{
_data = value;
UpdateCombinedField(_title, _description, _value);
}
}
public string CombinedField { get; set; }
public void UpdateCombinedField(title, description)
{
// some logic here extracts string values from json e.g. { k1: 'v1', k2: 'v2' } -> 'v1 v2'
CombinedField = title + " " + description + " " + extractedJsonValues;
}
}
这个想法是创建一个可以搜索的单个文本字段 - 不幸的是,由于 jsonb 的二进制性质,npgsql SearchVector option 不起作用。因此,UpdateCombinedField 创建了一个该字段的字符串,该字符串可以与其他字符串字段连接到CombinedField。
正如我所说的那样,问题是在应用迁移时填充CombinedField。
我尝试在 Migration 的 Up 方法中使用以下内容,该方法改编自上面的 SearchVector 指南,用于更新表:
migrationBuilder.Sql("UPDATE \"MyModels\" SET \"Title\" = \"Title\";");
但我不确定如何设置触发器以使上述代码正常工作,而不必将计算组合列的代码从类中取出并放入 SQL - 因此再次遇到 jsonb 二进制问题。
我们使用的是 postgresql 10。
总结需求,需要将文本列和 jsonb 列中的值组合到单个文本列中,当首次应用迁移时,该列也适用于现有行。此列是 Tsvector 是一个奖励,但不是必需的。
【问题讨论】:
标签: c# postgresql entity-framework-core npgsql