如何使此列与数据库中的PERSISTED COMPUTED列类似?
我当前的尝试(它在种子中加载所有带有null的CompCol行):
public class Call
{
public Call()
{
}
[Key]
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string CompCol
{
get
{
return "ABC-" + Convert.ToString(Id).PadLeft(5, '0');
}
protected set {}
}
}
答案 0 :(得分:9)
我找到的解决方案是:
确保已关闭自动迁移。这样VS就会生成一个脚本(流畅的api代码)供我们进一步定制而不是仅仅运行它。所以在配置类中:
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
将字段添加到类中并将其设置为计算如此,setter是私有的,因为我们显然无法写入计算字段:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string BreakdownNo { get; private set; }
然后在程序包管理器控制台中执行add-migration [xyz-name]
以生成迁移代码,该代码将显示在具有给定名称的迁移文件夹下。
在迁移内注释Up()
中的代码并添加自定义SQL,如下所示:
public override void Up()
{
//AddColumn("dbo.Calls", "BreakdownNo", c => c.String());
Sql("ALTER TABLE dbo.Calls ADD BreakdownNo AS ('BD'+RIGHT('00000'+ CAST(Id AS VARCHAR), 6))");
}
在PM中执行update-database
,它应该正确添加计算列。
进一步说明:如果您的公式错误,那么您必须通过执行update-database -targetMigration: [name of migration to go back to]
然后再做add-migration name
并在那里修改公式来恢复迁移,用update-database完成。可能有更好的方法,但这是我发现和使用的方式。
但是我没有办法让这个领域保持不变。
答案 1 :(得分:1)
为什么不这样调用sql:
public class demo
{
void demoMethod()
{
Model1 model = new Model1();//Model1 : DbContext
model.Database.ExecuteSqlCommand("alter table Results drop column Total; alter table Results add Total AS (Arabic + English + Math + Science)");
}
}
答案 2 :(得分:0)
我使用接受答案中提出的方法遇到了一些麻烦。我提供了另一种适合我的解决方案。
我在运行此查询时遇到了问题:
oDb.LogEntries.Where(Function(LogEntry) LogEntry.LogTime = dDate).SingleOrDefault
错误消息:
'LogEntry'上的'MinutesOffline'属性无法设置为'System.Int32'值。您必须将此属性设置为“System.Single”类型的非null值。
正如我们所看到的,EF 6.2正试图为该属性写一个值。这是否是由于EF内部尝试写入Private Set
,我不知道。它几乎就像它。但最终的结果才是最重要的:声明失败了。
我没有将列设置为DatabaseGeneratedOption.Computed
,而是完全忽略了它:Builder.Entity(Of LogEntry).Ignore(Function(LogEntry) LogEntry.MinutesOffline)
。
这使我能够创建一个只读属性:
Public ReadOnly Property MinutesOffline As Single
Get
Return IIf(Me.Scale < 1, 5, 0)
End Get
End Property
它还有一个额外的好处,我们不必在生成的迁移中注释掉任何行。
我们仍然需要在Sql()
中进行自定义Up()
来电:
ALTER TABLE [LogEntries] ADD [MinutesOffline] AS (IIF([Scale] < 1, 5, 0)) PERSISTED
... PERSISTED
关键字在此处有效。这将成为一个持久的计算列。
YMMV