假设我有一部电影租赁应用程序(DVD,Blueray或其他一些物理媒体),并且在用户返回电影后,他们可以对其进行评级。这是表格的简化版本:
Ratings
--------------------------------------------
| Id | UserId | MovieId | Rating (1 to 10) |
--------------------------------------------
Movies
------------------------------------------
| Id | Name | Computed rating (1 to 100) |
------------------------------------------
有没有办法配置Entity Framework来使用Ratings表中的条目计算电影的评级?因为在Movies表中有一个Rating字段会有点多余,我想知道Entity框架是否可以为我处理它而不必每次加载电影时都必须这样做。
我知道nHibernate可以将公式与属性相关联。
答案 0 :(得分:1)
计算聚合值将通过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);
}
}