Linq 联合两个表,其中有一个额外的列

Linq union two tables where on has an extra column

我正在使用 Union 来组合两个 tables auditmessage。它们都有相同的列名,除了 audit 有一个名为 deleteDate 的额外列。我尝试使用 Union 合并两个 table,如果 deleteDate 不存在,则将 DeleteDate 方法设置为 null。我评论了我想要开始工作的内容。当我取消注释代码时,出现错误。有解决办法吗?这是我的代码

    var audit = from a in _Audit.GetAll()
                       .Where(a => a.PInt == pInt && a.CreateDate < startDate && (endDate == null || endDate > a.CreateDate))
                       select new
                       {
                           a.MInt,
                           a.MId,
                           a.Desc,
                           a.PString,
                           a.PType,
                           a.MType,
                           a.CreateDate,
                           //    a.DeleteDate,
                           a.PInt
                       };

    var message = from a in _Message.GetAll()
           .Where(a => a.PartnerInt == partnerInt && a.CreateDate < startDate && (endDate == null || endDate > a.CreateDate))
                  select new
                  {
                      a.MInt,
                      a.MId,
                      a.Desc,
                      a.PString,
                      a.PType,
                      a.MType,
                      a.CDate,
                      a.PInt
                  };

    var test = from a in audit.Union(message)
               select new AuditMessagesGroup
               {
                   MInt = a.Int,
                   MId = a.Id,
                   Desc = a.Desc,
                   PString = a.PString,
                   PType = a.PayloadType,
                   MessageType = a.MType,
                   CreateDate = a.CreateDate,
         //          DeleteDate = a.DeleteDate != null ? a.DeleteDate : null,
                   PInt = a.PInt

               };

这里是错误

    Error   CS1929  'IQueryable<<anonymous type: int MInt, Guid 

MId, string Desc, string PString, string PType, 

MTypes MType, DateTime CreateDate, DateTime DeleteDate, int? 

PInt>>' does not contain a definition for 'Union' and the best 

extension method overload 'ParallelEnumerable.Union<<anonymous type: int 

MInt, Guid MId, string Desc, string PString, string 

PType, MTypes MType, DateTime CreateDate, int? PInt>>

(ParallelQuery<<anonymous type: int MInt, Guid MId, string 

Desc, string PString, string PType, MTypes 

MType, DateTime CreateDate, int? PInt>>, IEnumerable<<anonymous 

type: int MInt, Guid MId, string Desc, string 

PString, string PType, MTypes MType, DateTime 

CreateDate, int? PInt>>)' requires a receiver of type 

'ParallelQuery<<anonymous type: int MInt, Guid MId, string 

Desc, string PString, string PType, MTypes 

MType, DateTime CreateDate, int? PInt>>'    

不,你不能。联合的基本标准是列数必须匹配 b/w 个表。您可以生成一个虚拟列来绕过。喜欢

考虑 a.DeleteDateauditDateTime 将您的 message 更改为

var message = from a in _Message.GetAll()
       .Where(a => a.PartnerInt == partnerInt && a.CreateDate < startDate && (endDate == null || endDate > a.CreateDate))
              select new
              {
                  a.MInt,
                  a.MId,
                  a.Desc,
                  a.PString,
                  a.PType,
                  a.MType,
                  a.CDate,
                  DateTime.Now, // a dummy column
                  a.PInt
              };

然后你可以执行 UNION

要使 .Union(...) 工作,匿名类型 必须 完全相同 - 这要求它具有完全相同的字段数和完全相同的类型, 具有完全相同的名称。

因此,根据您的查询,我认为您需要这个:

var audit =
    from a in _Audit
        .GetAll()
        .Where(a => a.PInt == pInt)
        .Where(a => a.CreateDate < startDate)
        .Where(a => endDate == null || endDate > a.CreateDate)
    select new
    {
        a.MInt,
        a.MId,
        a.Desc,
        a.PString,
        a.PType,
        a.MType,
        a.CreateDate,
        a.DeleteDate,
        a.PInt
    };

var message =
    from a in _Message
        .GetAll()
        .Where(a => a.PartnerInt == partnerInt)
        .Where(a => a.CreateDate < startDate)
        .Where(a => endDate == null || endDate > a.CreateDate)
    select new
    {
        a.MInt,
        a.MId,
        a.Desc,
        a.PString,
        a.PType,
        a.MType,
        CreateDate = a.CDate,
        DeleteDate = (DateTime?)null,
        a.PInt
    };

我无法确定每种 table 的类型,但希望它们非常接近。

您可能需要使用 .ToArray() 将记录拉入内存,然后使用新的 .Select(...) 以使字段类型对齐,但​​假设它们已经相同它应该可以正常工作。