2015-04-11 2 views
1

У меня есть объект, который я хотел бы иметь свойство, которое содержит целое число, которое получает значение по количеству предыдущих сущностей, созданных в в тот же день.Как установить значение по умолчанию для свойства объекта, которое зависит от количества предыдущих

Предположим, у меня есть класс BooksOrder. Когда новый BooksOrder создан и сохранен в Db, мне бы хотелось, чтобы его свойство int DailyCount было равно BooksOrders.Where(bo => bo.Created.Day == DateTime.UtcNow.Day).Count() + 1

Где лучше всего было бы его реализовать? OnModelCreating определение DbContext? Если есть, как?

Или в файле определения миграции, отредактировав метод Up() и определите defaultValueSQL с SQL-запросом? Я использовал его с функцией GETDATE() Sql раньше для свойства DateTime, но не как в этом случае.

Третий путь я думаю, чтобы переопределить SaveChanges() метод DbContext:

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(); 
} 

Я думаю, это не будет работать, потому что он не будет препятствовать мне запрос DbSet BooksOrders внутри самой DbContext определения класса (если не статично, нам нужен istance, который не существует во время этого определения)

Вы, ребята, столкнулись с проблемой? Я был бы рад узнать, возможно ли это и как.

Благодаря

+0

Я хотел бы смотреть на сохранение этого производного значения обновленного асинхронно по отношению к остальной части системы, например, каждый раз, когда заказ книг был помещен или изменен, я бы поставил в очередь событие, на которое мог бы быть подписан нить, который затем пересчитывал и обновлял итоговую сумму Daily. Это также можно было бы отбросить, например. может ограничить обновление до максимума один раз в минуту и ​​т. д., если почти в реальном времени не требуется. – StuartLC

+0

@StuartLC Ну, асинхронная настройка этого значения не помогает мне в этой ситуации, мне нужно получить это почти мгновенно. Тем не менее, все альтернативы, которые приходят мне в голову, требуют от меня выполнения некоторых функций SQL/хранимых процедур, которые я не хочу делать. – Bogac

ответ

0

Несмотря на то, что я не хочу, чтобы попасть в хранимых процедур бизнеса, ну по крайней мере интегрирована с 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"); 
    }