Entity Framework Code First 计算属性

20
我正在使用ASP.NET MVC 3中的Entity Framework "Code First"方法。在我的数据库中,我有几个计算列。我需要使用这些列来显示数据(这很好地完成了)。但是,当我尝试向该表中插入行时,我遇到了以下错误:“ChargePointText”列无法修改,因为它要么是计算列,要么是UNION运算符的结果。是否有一种方法可以在我的类中将属性标记为只读?
public class Tariff
{
    public int TariffId { get; set; }
    public int Seq { get; set; }
    public int TariffType { get; set; }
    public int TariffValue { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public int ChargePoint { get; set; }
    public string ChargePointText { get; set; }
}

1
是的,你说得对 - 我的答案是不正确的。只有在你想让EF生成数据库时它才不起作用。将你的更新发布为答案并接受它。 - Ladislav Mrnka
2个回答

38

我已经找到了解决方法。Entity Framework 提供了一个名为 DatabaseGenerated 的数据注释。像这样使用:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string ChargePointText { get; set; }

这里可以获取更多详情:http://msdn.microsoft.com/en-us/library/gg193958.aspx


你能让它对UPDATE操作起作用吗?特别是针对模型类的“DateTime”属性,例如“LastUpdatedOn”属性? - Abhijeet Patel

3

还有几个其他选项。

第一个选项是在映射文件中更改属性设置,从:

this.Property(t => t.Name)
    .HasMaxLength(152);

to:

this.Property(t => t.Name)
    .HasMaxLength(152)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

这基本上与Same Huggill的解决方案相同,只是它将此配置保留在映射中,而不是模型中。我认为这样稍微好一些,因为映射类已经包含了告诉Entity Framework如何加载该类型实体的代码,所以知道一个字段是计算出来的应该放在那里。
另一种选择是NotMappedAttribute,它可以应用于实体的单个属性,如下所示:
public class User
{
    ...

    [NotMapped]
    public string Name
    {
        get;
        set;
    }

    ...
}

当实体包含未从数据库中填充的属性时,这很有用,但在OP面临的情况下同样有用,即EF不会尝试将值推送到标记有NotMappedAttribute的属性中,因此插入应该可以正常工作。


3
他正在尝试使用计算机生成的数据库字段。 "NotMapped" 无法帮助他实现这一点。 - Tory Netherton
2
是的,我做了。使用未映射属性将无法帮助他在应用程序中显示数据库计算字段,除非他也想在应用程序中计算它们。 - Tory Netherton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接