如何根据ID组合查询linq
How to query linq based on combinations of IDs
UserNotificationTypeDeliveryChoice - 已采用的组合
已采用的组合
(1,2),(3,2),(4,1),(4,2)
NotificationGroupUserType - 可能的组合
基于此table,自由组合为:
(1,1),(5,2)
任务:
我需要来自 NotificationGroupUserType table 的组合,其中不包含已采用的组合
一个例子:
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();
它 returns 只是 (5,2),因为它排除了 (1,1),因为 NotificationGroupId 已经存在,但不是与 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();
}
}
}
UserNotificationTypeDeliveryChoice - 已采用的组合
已采用的组合 (1,2),(3,2),(4,1),(4,2)
NotificationGroupUserType - 可能的组合
基于此table,自由组合为: (1,1),(5,2)
任务: 我需要来自 NotificationGroupUserType table 的组合,其中不包含已采用的组合
一个例子:
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();
它 returns 只是 (5,2),因为它排除了 (1,1),因为 NotificationGroupId 已经存在,但不是与 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();
}
}
}