2015-03-04 6 views
0

Я хочу удалить сущности, которые старше даты, и я хочу сделать это в общем виде. Причина в том, что существуют организации нескольких видов, и все они имеют ID и DateTime. Я использую ID и DateTime, чтобы делать запросы и регистрировать их.Как эффективно использовать выражения для предотвращения ошибки Entity Framework Указанный член типа не поддерживается в LINQ to Entities

Но у меня есть это исключение: Domain.DataAccessException: Removing old results failed ---> System.NotSupportedException: The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Теперь, когда я прочитал here, что мы должны создать выражение, чтобы сделать его более понятным для базы данных, как лечить эти свойства. Я думаю, я могу это сделать, но выражения сложны для компиляции.

Вопрос в том, какие наилучшие методы делают такие общие вещи, как это в Entity Framework? Является ли хороший подход к компиляции выражения только один раз для каждого типа объекта, а затем просто использовать его без затрат?

public interface IEntity 
{ 
    int ID { get; } 
    DateTime Date { get; } 
} 

public class DailyResult : IEntity { ... } 

public void ClearDaily(DateTime cutoffPoint) 
{ 
    CleanEntities<DailyResult>(cutoffPoint); 
}  

private void CleanEntities<TEntity>(DateTime cutoffPoint) where TEntity : class, IEntity 
{ 
    var set = context.Set<TEntity>().AsQueryable(); 

    var itemsToDelete = set.Where(x =>  DbFunctions.TruncateTime(x.Date).Value.CompareTo(cutoffPoint) == -1).ToArray(); 
    log.DebugFormat("Found {0} results", itemsToDelete.Length); 
    if (itemsToDelete.Any()) 
    { 
     var idsToDelete = string.Join(", ", itemsToDelete.Select(x =>  x.ID).ToArray()); 
     foreach (var entity in itemsToDelete) 
     { 
      MarkDelete(entity); 
     } 
     context.SaveChanges(); 

     log.InfoFormat("Removed records older than date {0}: {1}",  cutoffPoint.ToShortDateString(), idsToDelete); 
    } 
} 

private bool MarkDelete<T>(T entity) where T : class 
{ 
    context.Entry(entity).State = EntityState.Deleted; 
    return context.SaveChanges() > 0; 
} 
+0

DateTime не поддерживается (не уверен сейчас) попробуйте использовать DateTimeOffset – SWilko

ответ

0

IMHO TruncateTime(x.Date) оценивается как x.Date.Date, который не обрабатывается с помощью LINQ к объектам.

В вашем случае вы можете использовать

cutoffPoint = cutoffPoint.Date; 
var itemsToDelete = set.Where(x => x.Date < cutoffPoint).ToArray(); 

это не отвечает на основной вопрос. Для этого у вас есть интеграционный тест: тест, включающий уровень «бизнес» (где находятся ваши запросы) и уровень сохранения. Или, точнее, тест, не включающий насмешливый EF.

И/Или всегда проверяйте свой запрос в linqpad или же.

 Смежные вопросы

  • Нет связанных вопросов^_^