C# 如何使用自定义相等检查查询EF Core集合?
我有两个连接的表: 用户>设备 一个用户可以在FK user_ID上加入多个设备。设备表有一个主键ID。但设备也有一个被认为是唯一的令牌 我正在尝试选择没有令牌的用户: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
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]订购
您可能需要发布设备型号。