Посмотрите на следующий код, который демонстрирует, как использовать System.DateTime
в EF Core, и работает без проблем:
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace IssueConsoleTemplate
{
public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
public DateTime BestServedBefore { get; set; }
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySql(
"server=127.0.0.1;port=3306;user=root;password=;database=So61433252",
b => b.ServerVersion("8.0.20-mysql"))
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IceCream>()
.HasData(
new IceCream
{
IceCreamId = 1,
Name = "Vanilla",
BestServedBefore = DateTime.Today.AddDays(30)
},
new IceCream
{
IceCreamId = 2,
Name = "Chocolate",
BestServedBefore = new DateTime(2020, 5, 1)
}
);
}
}
internal class Program
{
private static void Main()
{
using (var context = new Context())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
// This code will work with *any* current culture, because EF Core and
// Pomelo don't use the current culture for DateTime formatting.
// Demonstrated here by explicitly setting the German culture.
// This is of course *not necessary* and just for demonstration
// puroposes.
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("de-DE");
// The following two queries use both, a literal `DATETIME`
// value and a `System.DateTime` parameter.
var today = DateTime.Today;
var badIceCreams = context.IceCreams
.Where(i => i.BestServedBefore <= new DateTime(2020, 5, 6) ||
i.BestServedBefore <= today)
.ToList();
var isAnyIceCreamBad = context.IceCreams
.Any(i => i.BestServedBefore <= new DateTime(2020, 5, 6) ||
i.BestServedBefore <= today);
Debug.Assert(badIceCreams.Count == 1);
Debug.Assert(badIceCreams[0].IceCreamId == 2);
Debug.Assert(isAnyIceCreamBad == true);
}
}
}
}
Он генерирует следующие SQL состояний:
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE `So61433252`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (24ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `IceCreams` (
`IceCreamId` int NOT NULL AUTO_INCREMENT,
`Name` longtext CHARACTER SET utf8mb4 NULL,
`BestServedBefore` datetime(6) NOT NULL,
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `BestServedBefore`, `Name`)
VALUES (1, '2020-06-05 00:00:00', 'Vanilla');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `BestServedBefore`, `Name`)
VALUES (2, '2020-05-01 00:00:00', 'Chocolate');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (8ms) [Parameters=[@__today_0='2020-05-06T00:00:00' (DbType = DateTime)], CommandType='Text', CommandTimeout='30']
SELECT `i`.`IceCreamId`, `i`.`BestServedBefore`, `i`.`Name`
FROM `IceCreams` AS `i`
WHERE (`i`.`BestServedBefore` <= '2020-05-06 00:00:00') OR (`i`.`BestServedBefore` <= @__today_0)
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[@__today_0='2020-05-06T00:00:00' (DbType = DateTime)], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1
FROM `IceCreams` AS `i`
WHERE (`i`.`BestServedBefore` <= '2020-05-06 00:00:00') OR (`i`.`BestServedBefore` <= @__today_0))
Как видите, даже если мы явно установили текущую культуру на de-DE
(которая использует формат даты dd.MM.yyyy HH:mm:ss
), значение System.DateTime
по-прежнему правильно отформатировано с использованием формата yyyy-MM-dd HH:mm:ss
:
WHERE (`i`.`BestServedBefore` <= '2020-05-06 00:00:00')
Однако, поскольку вы обычно используете переменные для фильтрации даты, эти переменные будут преобразованы в параметры, поэтому на практике ваши запросы вообще не будут содержать никаких литералов DATETIME
, а будут содержать только ссылки на параметры. Это можно увидеть в примере кода с использованием переменной today
, которая переводит в следующий фрагмент SQL:
OR (`i`.`BestServedBefore` <= @__today_0)
Наконец, вы можете видеть, что запрос Any()
LINQ преобразуется в SELECT EXISTS (SELECT 1 FROM ... WHERE ...)
SQL запрос, который отличается от того, который вы указали в своем вопросе.
Похоже, что вы делаете что-то очень неправильное в своем коде.