C# 使用LINQ to Entities返回一个对象集合,其中一个对象属性与另一个对象集合中的任何属性相匹配
我已经搜索了一整天,找不到解决这个问题的方法 我有一个C# 使用LINQ to Entities返回一个对象集合,其中一个对象属性与另一个对象集合中的任何属性相匹配,c#,linq,entity-framework,linq-to-entities,entitycollection,C#,Linq,Entity Framework,Linq To Entities,Entitycollection,我已经搜索了一整天,找不到解决这个问题的方法 我有一个EntityCollection的Communication对象,每个对象都有一个意图对象的实例(一对一) 我还有一个User对象,它有许多UserLocationEntityObjects(一对多)的实例 Intention对象具有属性UID UserLocation对象有一个属性LID 我想编写一个LINQ表达式,它返回所有Communication对象,其中与Communication对象关联的Intention实例的UID属性等于用
EntityCollection
的Communication
对象,每个对象都有一个意图
对象的实例(一对一)
我还有一个User
对象,它有许多UserLocation
EntityObjects
(一对多)的实例
对象具有属性Intention
李>UID
对象有一个属性UserLocation
LID
- 我想编写一个LINQ表达式,它返回所有
对象,其中与Communication
对象关联的Communication
实例的Intention
属性等于UID
用户的
实例的任何
属性反对LID
return _context.Communications.Where
(u => u.Intention.UID.Equals
(user.UserLocations.Select
(p => p.LID)));
还有这个
return _context.Communications.Where
(u => user.UserLocations.Any
(x => x.LID.Equals
(u.Intention.UID)));
还有这个
var thislist = from Intentions in _context.Intentions
join UserLocations in user.UserLocations
on Intentions.UID equals UserLocations.LID
select Intentions.UID;
return _context.Communications.Where(u => u.Intention.Equals(thislist.Any()));
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();
还有这个
var thislist = from Intentions in _context.Intentions
join UserLocations in user.UserLocations
on Intentions.UID equals UserLocations.LID
select Intentions.UID;
return _context.Communications.Where(u => u.Intention.Equals(thislist.Any()));
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();
(这在Contains语句中给出了一个错误,该语句表示“DelegateSystem.Func
不接受1个参数”,不知道如何修复)
除了所有这些变化,我还:
- 修改了我的方法以返回
,并且在将IQueryable
附加到我的查询时尝试了ToList()
李>List
namespace CollectionsWithIntentions
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
internal class Program
{
#region Methods
private static void Main(string[] args)
{
var communications = new[]
{
new Communication { Intention = new Intention { UID = 1 } },
new Communication { Intention = new Intention { UID = 2 } },
new Communication { Intention = new Intention { UID = 3 } },
new Communication { Intention = new Intention { UID = 4 } },
};
var users = new[]
{
new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 2 },new UserLocation{LID=5} }) },
new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 3 } }) }
};
IEnumerable<Communication> res =
communications.Where(w => users.Any(a => a.UserLocations.Any(b=>b.LID == w.Intention.UID)));
foreach (Communication communication in res)
{
Trace.WriteLine(communication);
}
}
#endregion
}
internal class Communication
{
#region Public Properties
public Intention Intention { get; set; }
#endregion
#region Public Methods and Operators
public override string ToString()
{
return string.Concat("Communication-> Intention:", this.Intention.UID);
}
#endregion
}
internal class Intention
{
#region Public Properties
public int UID { get; set; }
#endregion
}
internal class User
{
#region Public Properties
public List<UserLocation> UserLocations { get; set; }
#endregion
}
internal class UserLocation
{
#region Public Properties
public int LID { get; set; }
#endregion
}
}
我遗漏了什么吗?您在其中一条评论中链接的最后两个编译器错误 …我认为,
Intention.UID
是一种可为空的类型int?
,而不是您在评论中所说的不可为空的int
。这确实无法编译。尝试将上一个查询更改为:
var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications
.Where(x => x.Intention.UID.HasValue
&& lidlist.Contains(x.Intention.UID.Value))
.ToList();
其他三个查询不起作用,因为
user.UserLocations
是内存中非原始自定义类型的集合(对于要生成的SQL查询,它是一个“常量”值),EF不支持使用这种常量自定义类型构建SQL查询。UID和LID的类型是什么?嗯,第二种形式应该可以工作。为了清楚起见,我会使用=。我将尝试编写一个测试用例来确认。哪个委托不接受1个参数?通常,异常会精确地指定委托类型。您的方法返回什么类型?在我看来,最后一个代码应该有效。其他三个确实不起作用。我想我发现了第二个表格的问题。。。BRB@SlaumaSystem.FuncOne更正,我只搜索了一个用户,但您的代码看起来与我的第二个示例几乎完全相同。需要注意的另一个区别是,所有这些对象都是EntityObjects(用户位置、用户、通信、意图)或EntityCollections(用户位置)。UserLocations是两个实体“User”和“Location”之间的“桥接”对象。我可以确认通过EF会导致遇到相同的错误。。。调查答案在这本书中。因此,在您的情况下,首先必须将通信和用户位置强制转换到列表中。它的工作原理是:ctx.Communications.ToList().Where(w1=>user.Locations.ToList().Any(a1=>a1.LID==w1.intentials.UID)).ToList();你太棒了:)就是这样!我觉得把正手和正手结合在一起很合适。谢谢你的帮助@MattFoxxDuncan和Darek:注释中的解决方案非常糟糕,因为它将在应用过滤器之前首先将整个通信表加载到内存中。对于该表中的100条记录来说可能不是问题,但对于100000条或一百万条记录来说可能不是问题?