C# 多个Include和Where子句Linq

C# 多个Include和Where子句Linq,c#,linq,lambda,C#,Linq,Lambda,我有一个数据库,我想返回一个客户列表 这些客户有一个FamilyNames列表 我是从这个开始的 var query = DbContext.Clients.Include(c => c.FamilyNames).ToList() //returns all clients, including their FamilyNames...Great. 但我希望有人能够搜索FamilyName,如果返回任何结果,然后向用户显示客户端 所以我做了这个 var query = DbContext

我有一个数据库,我想返回一个客户列表

这些客户有一个FamilyNames列表

我是从这个开始的

var query = DbContext.Clients.Include(c => c.FamilyNames).ToList() //returns all clients, including their FamilyNames...Great.
但我希望有人能够搜索FamilyName,如果返回任何结果,然后向用户显示客户端

所以我做了这个

var query = DbContext.Clients.Include(c => c.FamilyNames.Where(fn => fn.familyName == textEnteredByUser)).ToList();
我试过

var query = DbContext.Clients.Include(c => c.FamilyNames.Any(fn => fn.familyName == textEnteredByUser)).ToList();
而且

var query = DbContext.FamilyNames.Include(c => c.Clients).where(fn => fn.familyname == textEnteredByUser.Select(c => c.Clients)).ToList();
我想知道的是(很明显!)我是如何让它工作的,但是如果可能的话,我希望它可以在一个数据库查询中完成。即使有人能给我指出正确的方向


在Linq to实体中,您可以在属性上导航,它们将转换为join语句

这将返回一个客户端列表

var query = DbContext.Clients.Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser)).ToList();
如果您希望在“即时加载”中包含其所有姓氏,则以下操作应有效:

var query = DbContext.Clients.Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser)).Include(c => c.FamilyNames).ToList();

这里有一些关于某些东西是否不能按预期工作的参考资料。

您可以使用“投影”,基本上您只需从任何级别选择所需的字段到新对象,可能是匿名的

var query = DbContext.Clients
    .Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser))
    // only calls that can be converted to SQL safely here
    .Select(c => new {
        ClientName = c.Name,
        FamilyNames = c.FamilyNames
    })
    // force the query to be materialized so we can safely do other transforms
    .ToList()
    // convert the anon class to what we need
    .Select(anon => new ClientViewModel() {
        ClientName = anon.ClientName,
        // convert IEnumerable<string> to List<string>
        FamilyNames = anon.FamilyNames.ToList()
    });
var query=DbContext.Clients
.Where(c=>c.FamilyNames.Any(fn=>fn==textEnteredByUser))
//此处仅允许安全地转换为SQL的调用
.选择(c=>new{
ClientName=c.Name,
FamilyNames=c.FamilyNames
})
//强制实现查询,以便我们可以安全地执行其他转换
托利斯先生()
//将anon类转换为我们需要的
.Select(anon=>newclientviewmodel(){
ClientName=anon.ClientName,
//将IEnumerable转换为列表
FamilyNames=anon.FamilyNames.ToList()
});
这将创建一个仅包含这两个属性的匿名类,然后强制运行查询,然后对ViewModel类执行第二次投影


通常我会选择一个ViewModel来传递给UI,将其限制为UI所需的最小字段数。您的需求可能会有所不同。

对不起,我回答得有点太快了。这是可行的,但我想包括的是客户,包括他们的家庭成员。谢谢,我认为这应该根据DbContext.Clients.Where(c=>c.FamilyNames.Any(fn=>fn==textEnteredByUser)).Include(c=>c.FamilyNames.ToList();是否执行查询?或者在运行时存在一些错误或异常?我遇到了嵌套IQueryable查询的问题,解决方案是在操作期间强制转换.AsEnumerable,并将一些数据带到memody。请写一些细节,也许我会提醒他们这会失败。ToList()无法通过linq转换为实体查询。@Cosmin是的,很抱歉我是在头脑中做这件事的,在我的代码中,我经常要投影两次,一次是DB safe调用,第二次是DB safe调用(如格式化、调用其他方法进行转换等)。我会更新我的答案。