C# 选择实体框架中其他表中不存在的记录

C# 选择实体框架中其他表中不存在的记录,c#,entity-framework,C#,Entity Framework,我有两个表-客户表和黑名单客户表。当我将客户列入黑名单时,我将customerid作为外键放入黑名单表 我想要的是得到不在黑名单表中的CusId和Name 如何编写这个实体框架C Customer --------- (CusId,Name,Telephone,Email) Blacklist --------- (CusId) 您需要的是以下内容: db.Customers .Where(c => !db.Blacklists .Select(b =>

我有两个表-客户表和黑名单客户表。当我将客户列入黑名单时,我将customerid作为外键放入黑名单表

我想要的是得到不在黑名单表中的CusId和Name

如何编写这个实体框架C

Customer
---------
(CusId,Name,Telephone,Email)

Blacklist
---------
(CusId)

您需要的是以下内容:

db.Customers
    .Where(c => !db.Blacklists
        .Select(b => b.CusId)
        .Contains(c.CusId)
    );
EF将很高兴地将其转换为一个运行良好的子查询

此模式适用于静态列表,创建INa、b、c表达式以及其他表。您可以使用它来检查是否在列表中


如果您想测试它并查看它生成的SQL,我强烈建议LINQPad它是免费的。这就是我在LINQ中一直用来测试小想法的东西。

这样的东西怎么样:

var subselect = (from b in BlackList select b.CusId).ToList();

var result = from c in Customer where !subselect.Contains(c.CusId) select c;
如果在黑名单表中有客户列表,您可以执行以下操作

 IEnumerable<Customer> model = (from c in db.Customer
                                from b in c.BlackList.DefaultIfEmpty()
                                 where b.CusID== null
                                  select new Customer
                                   {
                                        CusId= c.OrderID
                                    }).ToList();
任何一种都是最好的性能:


如果您还需要黑名单的列,请使用join with condition:b.CusId==c.Id

这个查询是我使用的,它可以完美地工作:

var query = _context.Customer.Where(x => x.Id == id && !x.BlackList.Any(z => x.Id == x.CustId)).ToList();

我是EF的新手,我已经尝试过我们的各种方法。他们没有一个成功。所以请帮我解决这件事。你有什么理由想这样做而不是像蒂莫西那样做吗?@PeterMajeed嗯,我不确定,但蒂姆只拿到过一次黑名单。Timothys黑名单被封装在一个Where中,但可能是EF优化了它,因此它只能被提取一次。我做的一次快速检查表明,对于我的代码,黑名单表被添加为一个Where NOT EXISTS,从[BlackList]中选择NULL作为[Empty]。。。所以它甚至没有检索到它,SQL做了所有的工作,而且它已经很好地优化了。对不起,伙计们。我只是提供了一些我以前用过的东西上面。当我发布我的答案时,我还没有看到任何其他答案。@TimRolen All good mate,有时候你的解决方案很方便,而且肯定有效。很高兴知道EF会将其转换为WHERE CusId NOT IN 1、2、3、4类型的语句。对于短列表,或者如果有额外的逻辑来过滤列表,这是最好的解决方案,那么我自己也要经常使用它。你能提供一个详细的版本,就像下面Tim提供的关于你上面的陈述的答案一样吗?那真的很有帮助。或者,如果您知道一个地方可以从一个转换到另一个,那就更好了:如何添加另一个Where子句?例如,其中Customer.Email=='a@a.com“??非常慢:如果黑名单表有100万条记录,它将不起作用,因为它总是给出短版本的时间错误:db.Customers.Wherec=>!db.Blacklists.Anyb=>b.CusId==c.CusId。但是,实体框架将生成相同的SQL表达式。
var query = _context.Customer.Where(x => x.Id == id && !x.BlackList.Any(z => x.Id == x.CustId)).ToList();