【发布时间】:2021-01-08 13:54:06
【问题描述】:
我有一些代码在查看单个数据库上下文时运行良好,但是当我将模型拆分为 2 个不同的上下文时,查询现在失败了。
所以我知道我不能在单个查询中使用 2 个不同的上下文,所以我尝试将一组提取到一个列表中,然后从查询中排除列表中的条目
var exclude = _traceContext.TraceDetails.Where(w => w.Trace.CreatedBy == userName).ToList();
var data = from s in _billingContext.log
where s.FormattedMessage.Contains(userName)
where !(
from l in exclude
select l.LogTime
).Contains(s.Timestamp)
select s;
这会导致转换错误:
SqlException:从字符串转换日期和/或时间时转换失败。
两列都是DateTime
如果我尝试生成数据为:
var data = _billingContext.log.Where(l => !exclude.Any(e => e.LogTime == l.Timestamp)).OrderBy(o => o.objID);
我明白了:
InvalidOperationException:LINQ 表达式 'DbSet .Where(y => !(__exclude_0 .Any(e => e.LogTime == y.Timestamp)))' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。
我不确定我在这里做错了什么。我需要的是log 的内容,其中exclude 的时间戳中没有任何LogTimes
使用 Contains 作为 Mong Zhu 的评论后编辑
所以我在使用 Contains 时仍然遇到转换错误,因此尝试拆分操作并确保我正在比较 2 个相同类型
var exclude = _traceContext.TraceDetails.Where(w => w.Trace.CreatedBy == userName).Select(f => f.LogTime.ToString("yyyy-MM-dd HH:mm:ss.fff")).ToList();
var data = _billingContext.YWAF_log.Where(s => s.FormattedMessage.Contains(userName));
var data2 = from d in data where !exclude.Contains(d.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff")) select d;
这让我得到'您的查询无法翻译...'
编辑 - 根据要求修改模型
public class Trace
{
[Key]
public int ObjID { get; set; }
public string Name { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string ServerName { get; set; }
public ICollection<TraceDetail> TraceDetails { get; set; }
}
public class TraceDetail
{
[Key]
public int ObjID { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss.fff}")]
public DateTime LogTime { get; set; }
public string ServiceName { get; set; }
public int Duration { get; set; }
public int? Threshold { get; set; }
public Trace Trace{ get; set; }
}
public class YWAF_log
{
[Key]
public int objID { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm.ss.fff}")]
public DateTime Timestamp { get; set; }
public string FormattedMessage { get; set; }
}
请注意,我无法在 objID 上进行匹配,因为它们是序列,并且由于数据库经常恢复,它们不会重新排序。
Trace 和 TraceDetail 在一个上下文中,而 YWAF_Log 在不同的上下文中 - 两个数据库都是 SQL Server 2008 R2
【问题讨论】:
-
日志文件中日期时间的格式是什么?日志文件是字符串/文本,因此您需要将字符串解析为 DateTime。
-
实体喜欢
Any,你必须使用Contains。 -
@jdweng 他们都是DateTime
-
方法
Contains将被转换为如下 SQL 表达式:WHERE x IN {..here are all values of your List..} -
TEXT 的日志文件如何成为 DATETIME 对象?
标签: c# .net asp.net-core entity-framework-core