EF Code First中的计算列

Cod*_*men 71 c# sql-server calculated-columns ef-code-first entity-framework-5

我需要在我的数据库中有一列由数据库计算为(行数之和) - (行数b).我正在使用代码优先模型来创建我的数据库.

这就是我的意思:

public class Income {
      [Key]
      public int UserID { get; set; }
      public double inSum { get; set; }
}

public class Outcome {
      [Key]
      public int UserID { get; set; }
      public double outSum { get; set; }
}

public class FirstTable {
      [Key]
      public int UserID { get; set; }
      public double Sum { get; set; } 
      // This needs to be calculated by DB as 
      // ( Select sum(inSum) FROM Income WHERE UserID = this.UserID) 
      // - (Select sum(outSum) FROM Outcome WHERE UserID = this.UserID)
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在EF CodeFirst中实现这一目标?

Ger*_*old 121

您可以在数据库表中创建计算列.在EF模型中,您只需使用属性注释相应的DatabaseGenerated属性:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public double Summ { get; private set; } 
Run Code Online (Sandbox Code Playgroud)

或者使用流畅的映射:

modelBuilder.Entity<Income>().Property(t => t.Summ)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
Run Code Online (Sandbox Code Playgroud)

正如Matija Grcic和评论中所建议的那样,创建属性是一个好主意private set,因为您可能永远不想在应用程序代码中设置它.私有制定者没有实体框架.

  • 我知道但是如何通过EF添加公式来计算它到我的数据库,以便它可以由控制台commad update-database创建? (18认同)
  • 请在您的问题中明确说明.这意味着您希望迁移创建计算列.有一个例子[这里](http://www.davepaquette.com/archive/2012/09/23/calculated-columns-in-entity-framework-code-first-migrations.aspx). (9认同)
  • 该答案应进行更新以添加针对EF Core的信息,模型构建器应使用方法ValueValueratedOnAddOrUpdate(),因为“ HasDatabaseGeneratedOption”不存在。否则,很好的答案。 (4认同)
  • +1给出注释和流畅的方式.谢谢. (3认同)
  • setter必须是私人的吗? (2认同)

Mat*_*cic 28

public string ChargePointText { get; set; }

public class FirstTable 
{
    [Key]
    public int UserID { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]      
    public string Summ 
    {
        get { return /* do your sum here */ }
        private set { /* needed for EF */ }
    }
}
Run Code Online (Sandbox Code Playgroud)

参考文献:


Pie*_*ier 25

截至 2019 年,EF 核心允许您使用 fluent API 以干净的方式计算列:

假设这DisplayName是您要定义的计算列,您必须像往常一样定义属性,可能使用私有属性访问器来防止分配它

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    // this will be computed
    public string DisplayName { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,在模型构建器中,使用列定义对其进行寻址:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .Property(p => p.DisplayName)
        // here is the computed query definition
        .HasComputedColumnSql("[LastName] + ', ' + [FirstName]");
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看MSDN

  • 这仅适用于 EF Core。该问题引用了 EF5,该方法不支持引用的方法。 (7认同)

Fer*_*ira 5

在 EF6 中,您只需配置映射设置即可忽略计算属性,如下所示:

定义模型的 get 属性的计算:

public class Person
{
    // ...
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName => $"{FirstName} {LastName}";
}
Run Code Online (Sandbox Code Playgroud)

然后在模型配置上将其设置为忽略

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    //...
    modelBuilder.Entity<Person>().Ignore(x => x.FullName)
}
Run Code Online (Sandbox Code Playgroud)