根据另一个表中的条目计算的实体框架属性

本文关键字:计算 实体 框架 属性 另一个 | 更新日期: 2023-09-27 18:20:48

假设我有一个电影租赁应用程序(DVD、Blueray或其他物理介质),用户返回电影后,他们可以对其进行评分。这是表格的简化版本:

Ratings
--------------------------------------------
| Id | UserId | MovieId | Rating (1 to 10) |
--------------------------------------------
Movies
------------------------------------------
| Id | Name | Computed rating (1 to 100) |
------------------------------------------

有没有一种方法可以配置实体框架来使用评分表中的条目计算电影的评分?因为在电影表中有一个评级字段会有点多余,我想知道实体框架是否可以为我处理它,而不必每次加载电影时都这样做。

我知道nHibernate可以将公式与属性联系起来。

根据另一个表中的条目计算的实体框架属性

计算聚合值将使用SQL触发器完成。

要创建触发器,您需要重写初始化器中的Seed方法(CreateDatabaseIfNotExists似乎适合您的情况)。

例如,给定以下模型-

public class Movie
{
    public string Name { get; set; }
    public int SumOfAllRatings { get; set; }
    public virtual Collection<Rating> Ratings { get; set; }
}
public class Rating
{
    public virtual Movie Movie { get; set; }
    public int Rating { get; set; }
}

和DbContext-

public class MyDbContext : DbContext
{
    public MyDbContext() : base()
    {
        Database.SetInitializer<MyDbContext>(new MyInitializer());
    }
    public DbSet<Movie> Movies { get; set; }
    public DbSet<Rating> Ratings { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Movie>().Property(m => m.SumOfAllRatings)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
    }
}

这是一个初始化器,它创建了一个合适的触发器-

public class MyInitializer : CreateDatabaseIfNotExists<MyDbContext>
{
  string _sql = "create trigger T_Ratings_Change " +
       "on dbo.Ratings after insert, update as " +
       "update Movies set SumOfAllRatings = " +
       "(select SUM(Rating) from Ratings where MovieId = inserted.MovieId) " +
       "from Movies inner join inserted ON Movies.Id = inserted.MovieId";

  protected override void Seed(MyContext context)
  {
    context.Database.ExecuteSqlCommand(_sql);
  }
}