【问题标题】:LINQ Exclude records using 2 different database contextsLINQ 使用 2 个不同的数据库上下文排除记录
【发布时间】: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


【解决方案1】:

将您的代码更改为:

var exclude = _traceContext.TraceDetails.Where(w => w.Trace.CreatedBy == userName).select(c => c.LogTime).ToList();

var data = from s in _billingContext.log
                   where s.FormattedMessage.Contains(userName)
                   and
                     !exclude.Contains(s.Timestamp)
                   select s;

【讨论】:

  • 这给出了同样的错误:SqlException: Conversion failed when convert date and/or time from string.
  • 你支持LogTime和Timestamp是同一个数据类型吗?
猜你喜欢
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-20
相关资源
最近更新 更多