C# 如何基于IDs组合查询linq

C# 如何基于IDs组合查询linq,c#,asp.net,linq,linq-to-sql,C#,Asp.net,Linq,Linq To Sql,UserNotificationTypeDeliveryChoice-已使用组合 已采取的组合 (1,2)、(3,2)、(4,1)、(4,2) NotificationGroupUserType-可能的组合 根据该表,自由组合为: (1,1)、(5,2) 任务: 我需要NotificationGroupUserType表中的组合,该表不包含已采取的组合 例如: List<int> notificationGroupIds = selectedNotificationsByUser

UserNotificationTypeDeliveryChoice-已使用组合

已采取的组合 (1,2)、(3,2)、(4,1)、(4,2)

NotificationGroupUserType-可能的组合

根据该表,自由组合为: (1,1)、(5,2)

任务: 我需要NotificationGroupUserType表中的组合,该表不包含已采取的组合

例如:

List<int> notificationGroupIds = selectedNotificationsByUser
    .Select(m => (int)m.NotificationGroupId)
    .ToList();
List<int> deliveryTypeIds = selectedNotificationsByUser
    .Select(m => (int)m.DeliveryTypeId)
    .ToList();

var result = _dbContext.NotificationGroupUserType
    .Include(m => m.NotificationGroup)
    .Include(m => m.DeliveryType)
    .Where(m => m.UserTypeId == (int)userType
        && !notificationGroupIds.Contains((int)m.NotificationGroupId)
        || !deliveryTypeIds.Contains((int)m.DeliveryTypeId)
    )
    .Select(m => new NotificationGroupUserType()
    {
        DeliveryType = m.DeliveryType,
        NotificationGroup = m.NotificationGroup
    })
    .ToList();
List notificationGroupIds=selectedNotificationsByUser
.选择(m=>(int)m.NotificationGroupId)
.ToList();
List DeliveryTypeId=SelectedNotificationsByser
.Select(m=>(int)m.DeliveryTypeId)
.ToList();
var result=\u dbContext.NotificationGroupUserType
.包括(m=>m.NotificationGroup)
.包括(m=>m.DeliveryType)
.Where(m=>m.UserTypeId==(int)userType
&&!NotificationGroupId.Contains((int)m.NotificationGroupId)
||!DeliveryTypeId.Contains((int)m.DeliveryTypeId)
)
.Select(m=>newnotificationgroupusertype()
{
DeliveryType=m.DeliveryType,
NotificationGroup=m.NotificationGroup
})
.ToList();

它只返回(5,2),因为它因NotificationGroupId而排除(1,1)的项已经存在,但不是与1的组合

这是因为您可以独立测试两个ID,而不是成对测试。尝试使用匿名类型:

var notifications = selectedNotificationsByUser
    .Select(n => new { n.NotificationGroupId, n.DeliveryTypeId })
    .Distinct()
    .ToList();

var result = _dbContext.NotificationGroupUserType
    .Include(m => m.NotificationGroup)
    .Include(m => m.DeliveryType)
    .Where(m => m.UserTypeId == (int)userType &&
        !notifications.Contains(new { m.NotificationGroupId, m.DeliveryTypeId }))
    .Select(m => new NotificationGroupUserType() {
        DeliveryType = m.DeliveryType,
        NotificationGroup = m.NotificationGroup
    })
    .ToList();
如果LINQ to SQL无法将表达式转换为SQL,则可以尝试以下操作:

var result = _dbContext.NotificationGroupUserType
    .Include(m => m.NotificationGroup)
    .Include(m => m.DeliveryType)
    .Where(m => m.UserTypeId == (int)userType)
    .AsEnumerable() // Following part is LINQ-to-Objects
    .Where(m => !notifications.Contains(new { m.NotificationGroupId, m.DeliveryTypeId }))
    .Select(m => new NotificationGroupUserType() {
        DeliveryType = m.DeliveryType,
        NotificationGroup = m.NotificationGroup
    })
    .ToList();
请尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
         static void Main(string[] args)
         {
             DataTable dt = new DataTable();
             dt.Columns.Add("NotificationGroupId", typeof(int));
             dt.Columns.Add("DeliveryTypeId", typeof(int));

             dt.Rows.Add(new object[] { 1, 1 });
             dt.Rows.Add(new object[] { 3, 2 });
             dt.Rows.Add(new object[] { 4, 1 });
             dt.Rows.Add(new object[] { 4, 2 });
             dt.Rows.Add(new object[] { 5, 2 });
             dt.Rows.Add(new object[] { 1, 1 });
             dt.Rows.Add(new object[] { 3, 2 });
             dt.Rows.Add(new object[] { 4, 1 });
             dt.Rows.Add(new object[] { 4, 2 });
             dt.Rows.Add(new object[] { 5, 2 });

             List <CompareID> ids = dt.AsEnumerable()
                 .Select(x => new CompareID() { NotificationGroupId = x.Field<int>("NotificationGroupId"), DeliveryTypeId = x.Field<int>("DeliveryTypeId") })
                 .Distinct()
                 .ToList();

             Boolean found = ids.Contains(new CompareID() { NotificationGroupId = 5, DeliveryTypeId = 5 });

         }
    }
    public class CompareID : IEquatable <CompareID>
    {
        public int NotificationGroupId { get; set; }
        public int DeliveryTypeId { get; set; }

        public bool Equals(CompareID other)
        {
            if ((this.NotificationGroupId == other.NotificationGroupId) && (this.DeliveryTypeId == other.DeliveryTypeId))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public override bool Equals(Object obj)
        {
            return this.Equals((CompareID)obj);
        }

        public override int GetHashCode()
        {
            return (NotificationGroupId.ToString() + "^" + DeliveryTypeId.ToString()).GetHashCode();
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统数据;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
DataTable dt=新的DataTable();
添加(“NotificationGroupId”,typeof(int));
添加(“DeliveryTypeId”,typeof(int));
Add(新对象[]{1,1});
Add(新对象[]{3,2});
Add(新对象[]{4,1});
Add(新对象[]{4,2});
Add(新对象[]{5,2});
Add(新对象[]{1,1});
Add(新对象[]{3,2});
Add(新对象[]{4,1});
Add(新对象[]{4,2});
Add(新对象[]{5,2});
列表ID=dt.AsEnumerable()
.Select(x=>newcompareId(){NotificationGroupId=x.Field(“NotificationGroupId”),DeliveryTypeId=x.Field(“DeliveryTypeId”)})
.Distinct()
.ToList();
Boolean found=ids.Contains(new CompareID(){NotificationGroupId=5,DeliveryTypeId=5});
}
}
公共类CompareID:IEquatable
{
public int NotificationGroupId{get;set;}
public int DeliveryTypeId{get;set;}
公共布尔等于(比较其他)
{
if((this.NotificationGroupId==other.NotificationGroupId)&&(this.DeliveryTypeId==other.DeliveryTypeId))
{
返回true;
}
其他的
{
返回false;
}
}
公共覆盖布尔等于(对象对象对象)
{
返回这个.Equals((CompareID)obj);
}
公共覆盖int GetHashCode()
{
return(NotificationGroupId.ToString()+“^”+DeliveryTypeId.ToString()).GetHashCode();
}
}
}

使用ICompare界面,以便使用Distinct。你能给我举个例子吗?谢谢。它工作得很好。我需要这一行。Contains(new{…})。