Я делал несколько тестов, используя Entity Framework. Net core. Я включил SQL профиль сервера и начал сравнивать свой запрос и то, что EF выполняет на SQL Сервере.
Вот мой модальный класс:
public class Offer : BaseModel
{
public DateTime HostStartDate { get; set; }
public DateTime HostEndDate { get; set; }
public int Guests { get; set; }
public decimal AmountOffer { get; set; }
public OfferStatus Status { get; set; }
public PaymentStatus PaymentStatus { get; set; }
public long CityId { get; set; }
public virtual City City { get; set; }
[Required]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
public virtual ICollection<Bid> Bids { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public bool IsVisible => HostStartDate.Date >= DateTime.Today.Date;
public void SetSoftDelete()
{
IsDeleted = true;
Bids.ToList().ForEach(n => n.SetSoftDelete());
}
}
public class Bid : BaseModel , IStateAware
{
[NotMapped]
public override long Id { get; set; }
public long OfferId { get; set; }
public virtual Offer Offer { get; set; }
public long PropertyId { get; set; }
public virtual Property Property { get; set; }
public DateTime? Accepted { get; set; }
public bool Read { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public ModelState State { get; set; }
[NotMapped]
public bool IsPayed => Accepted.HasValue;
[NotMapped]
public bool IsAccepted => Accepted.IsNotNull();
public void SetSoftDelete()
{
IsDeleted = true;
State = ModelState.Modified;
}
}
У меня есть generi c класс для выполнения поиска, например:
public IQueryable<TEntity> FindBy(
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> includeProperty = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
{
IQueryable<TEntity> query = context.Set<TEntity>();
if (filter.IsNotNull())
{
query = query.Where(filter);
}
if (includeProperty.IsNotNull())
{
query = query.Include(includeProperty);
}
if (orderBy.IsNotNull())
{
query = orderBy(query);
}
return query.AsNoTracking();
}
Я называю это так:
var finalEnd = new DateTime(end.Year, end.Month, end.Day, 23, 59, 59);
var data = await _bidRepo.FindBy(n => !n.OfferId.Equals(offerId)
&& n.PropertyId.Equals(propertyId)
&& !n.IsDeleted
&& !n.IsAccepted
&& !n.IsPayed
&& !n.IsInvalidate
&& ((n.Offer.HostStartDate.Date >= start.Date && n.Offer.HostStartDate.Date <= end.Date) ||
(n.Offer.HostEndDate > finalEnd && n.Offer.HostEndDate.Date <= end.Date))
).ToListAsync();
Мой запрос возвращает 4 элемента, и это нормально. Но на SQL профиле сервера мой запрос не заботится ни о чем, кроме даты.
Это профиль:
exec sp_executesql N'SELECT [n].[OfferId], [n].[PropertyId], [n].[Accepted], [n].[CreatedBy], [n].[CreatedDate], [n].[IsDeleted], [n].[IsInvalidate], [n].[ModifiedBy], [n].[ModifiedDate], [n].[Read]
FROM [Bids] AS [n]
INNER JOIN [Offers] AS [n.Offer] ON [n].[OfferId] = [n.Offer].[Id]
WHERE ((CONVERT(date, [n.Offer].[HostStartDate]) >= @__start_Date_2) AND (CONVERT(date, [n.Offer].[HostStartDate]) <= @__end_Date_3)) OR (([n.Offer].[HostEndDate] > @__finalEnd_4) AND (CONVERT(date, [n.Offer].[HostEndDate]) <= @__end_Date_3))',N'@__start_Date_2 datetime2(7),@__end_Date_3 datetime2(7),@__finalEnd_4 datetime2(7)',@__start_Date_2='2020-02-23 00:00:00',@__end_Date_3='2020-02-25 00:00:00',@__finalEnd_4='2020-02-25 23:59:59'
В этом SQL заявлении сервера, Я не вижу ни одного из логических фильтров или идентификаторов.
Как я могу убедиться, что все предложения выполняются на сервере SQL и не переносят часть даты в C#, а затем удаляют ее?