首页 > 解决方案 > LINQ 使用 2 个不同的数据库上下文排除记录

问题描述

我有一些代码在查看单个数据库上下文时运行良好,但是当我将模型拆分为 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没有任何 LogTimes 在 Timestamps 中的内容exclude

编辑使用包含作为蒙朱的评论后

所以我在使用 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

标签: c#.netasp.net-coreentity-framework-core

解决方案


将您的代码更改为:

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;

推荐阅读