【问题标题】:How to set a default value for a property of an entity that depends on count of previous ones如何为依赖于先前数量的实体的属性设置默认值
【发布时间】:2015-04-11 11:11:43
【问题描述】:

我有一个实体,我想拥有一个属性,该属性包含一个整数,该整数通过在同一天创建的先前实体的计数来获取值。

假设我有 BooksOrder 课程。当一个新的 BooksOrder 创建并保存到 Db 时,我希望它的属性 int DailyCount 等于 BooksOrders.Where(bo => bo.Created.Day == DateTime.UtcNow.Day).Count() + 1

实施它的最佳地点在哪里? OnModelCreating DbContext 的定义? 如果有,怎么做?

或者在迁移定义文件中,通过编辑Up() 方法并使用SQL 查询定义defaultValueSQL?我之前确实将它与 GETDATE() Sql 函数一起用于 DateTime 属性,但在这种情况下不像。

我想到的第三种方法是重写 DbContext 的 SaveChanges() 方法:

public override int SaveChanges()
{
    var AddedBooksOrders = ChangeTracker.Entries()
        .Where(e => e.State == EntityState.Added && e.Entity is BooksOrder)
        .Select(e => e.Entity).Cast<BooksOrder>();

    foreach (var abo in AddedBooksOrders)
    {
        abo.DailyCount = BooksOrders.Where(bo => bo.Created.Day == DateTime.UtcNow.Day).Count() + 1;
    }

    return base.SaveChanges();
}

我的猜测是这行不通,因为它不允许我在 DbContext 类定义本身中查询 DbSet BooksOrders(如果不是静态的,我们需要一个 istance,在此定义时不存在)

你们遇到过类似的问题吗?我很高兴知道这是否可行以及如何实现。

谢谢

【问题讨论】:

  • 我会考虑保持这个派生值与系统的其余部分异步更新,例如每次下达或修改图书订单时,我都会排队一个事件,该事件可以由一个线程订阅,然后重新计算和更新每日运行总数。这也可以去抖动,例如如果不需要接近实时,可以将更新限制为每分钟最多一次等。
  • @StuartLC 好吧,在这种情况下,该值的异步设置对我没有帮助,我需要几乎立即得到它。然而,我想到的所有替代方案都需要我做一些 SQL 函数/存储过程干预,这不是我想做的。

标签: c# entity-framework entity-framework-6


【解决方案1】:

尽管我不想涉足存储过程业务,但至少与 EF Code First 集成,而且我实际上对解决方案感到满意。 首先,我将该属性添加到我的实体中:

public int DailyCount { get; set; }

然后,包管理器:add-migration "WithDailyCount"。最后,在迁移定义中将存储过程代码添加到Up() 方法(以及在Down() 方法中删除它的那个)

    public override void Up()
    {
        AddColumn("myDb.BookOrders", "DailyCount", c => c.Int(nullable: false));

        Sql(string.Format(@"                
                    CREATE PROCEDURE [myDb].[DailyCountIncrement]
                    AS
                    BEGIN
                        DECLARE @DCountPlusOne int
                        SET @DCountPlusOne .....More SQL code here to read and increment count goes here
                        SELECT @DCountPlusOne 
                    END"));
    }

    public override void Down()
    {
        DropColumn("myDb.BookOrders", "DailyCount");
        DropStoredProcedure("myDb.DailyCountIncrement");
    }

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2013-01-05
    • 2011-08-19
    • 1970-01-01
    • 2011-03-07
    • 2011-12-01
    • 2013-11-18
    • 1970-01-01
    相关资源
    最近更新 更多