sqlsugar与EFcore混用,对DateTime的处理出现了问题 返回
SqlSugar
沟通中
3
242
ck0077 发布于2周前
悬赏:0 飞吻
项目数据库为pgsql,项目中使用了TickerQ定时库,这个定时库必须使用pgsql的EFcore来读写数据。
<ItemGroup> <PackageReference Include="TickerQ" Version="10.3.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" /> <PackageReference Include="TickerQ.EntityFrameworkCore" Version="10.3.0" /> </ItemGroup>
// 要使用ContextFactory来初始化表
public class TickerQDbContextFactory : IDesignTimeDbContextFactory<TickerQDbContext>
{
public TickerQDbContext CreateDbContext(string[] args)
{
var options = new DbContextOptionsBuilder<TickerQDbContext>()
.UseNpgsql(
"Server=xxxxxx;Port=5432;Database=yyy;Uid=admin;Pwd=123456;",
builder => builder.MigrationsAssembly("MyProjectName")
)
.Options;
return new TickerQDbContext(options);
// dotnet ef migrations add InitTickerQ --context TickerQDbContext
// dotnet ef database update --context TickerQDbContext
}
}
// 注入TickerQ
builder.Services.AddTickerQ(optionsBuilder =>
{
// Core configuration
optionsBuilder.ConfigureScheduler(schedulerOptions =>
{
schedulerOptions.MaxConcurrency = 5;
schedulerOptions.NodeIdentifier = "bot-server";
schedulerOptions.FallbackIntervalChecker = TimeSpan.FromSeconds(30);
});
// Configure the EF Core–backed operational store for TickerQ metadata, locks, and state.
optionsBuilder.AddOperationalStore(efOptions =>
{
efOptions.UseTickerQDbContext<TickerQDbContext>(builder =>
{
builder.UseNpgsql(
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
cfg => cfg.EnableRetryOnFailure(3, TimeSpan.FromSeconds(5), null)
);
});
efOptions.SetDbContextPoolSize(5);
});
});
// 使用TickerQ
app.UseTickerQ();业务类定义大致如下
public class SysUserRole
{
/// <summary>
/// 用户Id
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string RoleName { get; set; } = null!;
/// <summary>
/// 开始时间
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime EndTime { get; set; }
}
先不注入TickerQ,先使用sqlsugar插入一条数据
sugarClient.Insertable(new SysUserRole()
{
UserId = 1,
RoleName = "test",
StartTime = utcNow.Subtract(TimeSpan.FromMinutes(5)),
EndTime = utcNow.AddMinutes(10),
})
.ExecuteCommand();然后停掉项目,注入TickerQ,再在项目里执行查询
var utcNow = DateTime.UtcNow; var alertTime = utcNow.AddMinutes(15); // 提前15分钟提醒 var userRoles = sugarClient.Queryable<SysUserRole>() // .Where(r => r.EndTime > utcNow && r.EndTime < alertTime) // .Where(r => r.EndTime < alertTime) .Where(r => r.EndTime > utcNow) .ToList();
发现无数据返回,打印sql后,检查sql语句没有问题(直接在datagrip中执行也没有问题,能查到数据)。
如果不注入TickerQ( 项目内没有UseNpgsql(....) ),则查询正常,有数据返回。
后面手动修改数据库记录,发现是数据库的EndTime的被当成了本地时间处理(减了8小时),再去与传入的utcNow进行比较,导致条件判断失败。
请问这种情况能怎么处理呢。数据类现在只能是DataTime,无法改成DataTimeOffset。
热忱回答(3)
-
fate sta VIP0
2周前你看一下自定义类型。
0 回复 -
fate sta VIP0
2周前个别表可以用自定义类型处理,如果是所有表那就需要研究原因了。我不清楚你这个库的机质。
0 回复 -
ck0077 VIP0
2周前找到了一个解决办法,就是在连接字符串的后面加上"Timezone=UTC",让pgsql把时间全部当成utc时间处理。
我还得单独去引用一下EF core,看看是这个定时库的原因还是EF core自身的原因。0 回复