C# 如何使用自定义相等检查查询EF Core集合?

C# 如何使用自定义相等检查查询EF Core集合?,c#,.net-core,ef-core-2.1,C#,.net Core,Ef Core 2.1,我有两个连接的表: 用户>设备 一个用户可以在FK user_ID上加入多个设备。设备表有一个主键ID。但设备也有一个被认为是唯一的令牌 我正在尝试选择没有令牌的用户: IQueryable users=DbContext.users.Where(u=>u.ID===\u ID&!u.Devices.Contains(device)); 此处传递的设备有一个令牌,设备模型有一个等于,并且GetHashCode覆盖了仅在令牌上进行的相等测试: public bool等于(设备组件) { 返回co

我有两个连接的表:

用户>设备

一个用户可以在FK user_ID上加入多个设备。设备表有一个主键ID。但设备也有一个被认为是唯一的令牌

我正在尝试选择没有令牌的用户:

IQueryable users=DbContext.users.Where(u=>u.ID===\u ID&!u.Devices.Contains(device));
此处传递的
设备
有一个令牌,
设备
模型有一个
等于
,并且
GetHashCode
覆盖了仅在令牌上进行的相等测试:

public bool等于(设备组件)
{
返回comp.DeviceId.Equals(this.DeviceId);
}
因此,如果我先选择用户,然后在代码查询设备集合中,我可以检查用户是否尚未关联设备:

IQueryable users=DbContext.users.Where(u=>u.ID==\u ID);
User=users.First();
如果(!user.Devices.Contains(设备))
{
…此处包含仅基于设备令牌比较的设备
}
但是EF Core构造了查询:

选择TOP(1)[u].[ID],…{为简洁起见剪切的其他用户属性}
来自[用户]作为[用户]
其中([u].[ID]=@u ID_0)和@u 8_ulocals1_device_1_ID不在(
选择[d]。[Id]
从[设备]作为[d]
其中[u].[ID]=[d].[User\u ID]
)
在我看来,我只能根据设备的ID属性测试是否相等


有没有办法构造一个EF核心查询来匹配代码相等性/GetHashCode检查,或者我必须在代码中这样做?

我重复了你的案例。请在下面查找代码。有关解释,请参见注释

// user class
public partial class tempu
{
    public int id { get; set; }
    [StringLength(50)]
    public string name { get; set; }
    public List<tempd> tempds { get; set; }
}

// device class
public partial class tempd
{
    public int? token { get; set; }
    public int? uid { get; set; }
    [StringLength(50)]
    public string name { get; set; }
    public int id { get; set; }
    public tempu tempus { get; set; }
}

// context
modelBuilder.Entity<tempu>(entity =>
{
    entity.ToTable("tempu");
});

//// this is do the mapping of one to many
modelBuilder.Entity<tempd>(entity =>
{
    entity.ToTable("tempd")
    .HasOne(p => p.tempus)
    .WithMany(i => i.tempds)
    .HasForeignKey(b => b.uid);
});

// linq query
var results = _context.tempu
      .Where(t => t.tempds.Any(y => y.token == null)) //// this will check if device id can be null in any case, 
      .Include(s => s.tempds) //// this will do the join
      .ToList();

// generated sql
SELECT [t].[id], [t].[name]
FROM [tempu] AS [t]
WHERE EXISTS (
    SELECT 1
    FROM [tempd] AS [y]
    WHERE [y].[token] IS NULL AND ([t].[id] = [y].[uid]))
ORDER BY [t].[id] 
//用户类
公共部分类tempu
{
公共int id{get;set;}
[长度(50)]
公共字符串名称{get;set;}
公共列表tempds{get;set;}
}
//设备类
公共部分班临时工
{
公共int?标记{get;set;}
公共int?uid{get;set;}
[长度(50)]
公共字符串名称{get;set;}
公共int id{get;set;}
公共tempu tempus{get;set;}
}
//上下文
modelBuilder.Entity(Entity=>
{
实体。可转帐(“tempu”);
});
////这就是一对多的映射
modelBuilder.Entity(Entity=>
{
实体。可转帐(“tempd”)
.HasOne(p=>p.tempus)
.WithMany(i=>i.tempD)
.HasForeignKey(b=>b.uid);
});
//linq查询
var results=\u context.tempu
.Where(t=>t.tempds.Any(y=>y.token==null))///这将检查设备id在任何情况下是否可以为null,
.Include(s=>s.tempds)///这将进行连接
.ToList();
//生成的sql
选择[t].[id],[t].[name]
从[tempu]AS[t]
哪里有(
选择1
从[tempd]AS[y]
其中,[y].[token]为空且([t].[id]=[y].[uid]))
由[t].[id]订购

您可能需要发布设备型号。