C# - 在 Linq Where Any 语句中使用的要列出的字符串

Posted

技术标签:

【中文标题】C# - 在 Linq Where Any 语句中使用的要列出的字符串【英文标题】:C# - String to list used in Linq Where Any statement 【发布时间】:2021-10-06 13:27:36 【问题描述】:

我想使用这个字符串作为过滤器来删除 linq 查询中的一些 Id

public class ProductKitMakerDto

    public int Id  get; set; 
    public string TitleShort  get; set; 
    public string Media  get; set; 


[HttpPost]
public ActionResult KitItemSelect(string culture)

    string productMakerIds = "4174,2196,2201,2460,2508,2204";

    //create a list
    var productMakerList = new List<ProductKitMakerDto>();
    foreach (int i in productMakerIds)
    
        productMakerList.Add(new ProductKitMakerDto  Id = i );
    

    var itemselects = (from p in _context.Products
                   where p.Matrix == 2400
                   select new ProductKitMakerDto()
                   
                   Id = p.Id,
                   TitleShort = culture == "de" ? p.TitleShortDe :
                                culture == "fr" ? p.TitleShortFr :
                                p.TitleShortEn,
                    Media = "/img/" + p.Photo,
                    ).ToList();

    //From this query I get 40 results.
    //Then I want to remove the ones from the list:

    //itemselects = itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));

    //1st (above) I get an Error CS0266 asking for explicit cast. So aplly the modification

    itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));

    return Json(itemselects, JsonRequestBehavior.AllowGet);

我得到 500(内部服务器错误) - xhr.send( options.hasContent && options.data || null ); 我猜这个列表是空的。 任何想法?谢谢

【问题讨论】:

其中一个生产标记 id 是 4174 ??或 4 @behroozbc 4174!它们有一个逗号分隔符。 foreach (int i in productMakerIds) 不起作用。您需要 Split 您的 productMakerIds 并将各个字符串解析为整数。 @Filburt:我试过 var productMakerList = ProductMakerIds.Split(',').Select(int.Parse).ToList();和 var productMakerList = ProductMakerIds.Split(',').ToList().Select(int.Parse).ToList();然后 itemselects = itemselects.Where(i => !productMakerList.Contains(i.Id));但我收到错误:在 System.Collections.Generic.List 中输入 System.Collections.Generic.IEnumerable “要求显式转换” Enumerable.Where 不返回列表,因此将其转换为一个没有意义,而是在Where 之后附加ToList 【参考方案1】:
foreach (string i in productMakerIds.Split(','))
    
        productMakerList.Add(new ProductKitMakerDto  Id = int.Parse(i) );
    

【讨论】:

这个解决方案对我来说看起来不错,但我收到 500 错误 xhr.send( options.hasContent && options.data || null ) 按照 TimSchmelter 的建议添加 ToList() 可以完美运行。谢谢 @Philippe 帮自己一个忙,通过在后端代码中设置断点来学习如何调试,而不是想知道前端错误消息。它并不总是像在这种情况下那样明显,并且在此处发布时,500 Internal Server Error 并不是有用的调试信息。 @Filburt 承诺,我会的 ;-)【参考方案2】:

    这不起作用

    string productMakerIds = "4174,2196,2201,2460,2508,2204";
    var productMakerList = new List<ProductKitMakerDto>();
    foreach (int i in productMakerIds)
    
        productMakerList.Add(new ProductKitMakerDto  Id = i );
    
    

因为您需要先以逗号分隔并将string 解析为int

   foreach (string i in productMakerIds.Split(',')) // and parse i to int with int.Parse

    但由于它是字符串文字,因此首先要正确初始化它。不要使用List&lt;ProductKitMakerDto&gt;,因为你只需要List&lt;int&gt;,那么你可以使用Contains

    var productMakerList = new List<int>
    
        4174, 2196, 2201, 2460, 2508 , 2204
    ;
    

    如果它不是一个列表并且Enumerable.Where 不返回一个列表,则不能转换为列表:

    itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
    

您需要在Where 之后附加ToList

   itemselects = itemselects
       .Where(i => !productMakerList.Any(pml =>pml.Id == i.Id))
       .ToList();

但如前所述,您也可以在第一次创建该列表之前使用此 Where,因此应包含应支持的 Contains 条件:

var itemselects = (from p in _context.Products
                   where p.Matrix == 2400
                   && !productMakerList.Contains(p.Id)
                   select new ProductKitMakerDto()
                   
                      Id = p.Id,
                      TitleShort = culture == "de" 
                         ? p.TitleShortDe 
                         : culture == "fr" ? p.TitleShortFr : p.TitleShortEn,
                      Media = "/img/" + p.Photo,
                   ).ToList();

【讨论】:

奇怪的是这完美地工作: itemselects = itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id)).ToList();而你之前对 Where 子句的最后建议给了我一个 500 错误 @Philippe:我已经编辑了我的答案。不要创建 List&lt;ProductKitMakerDto&gt;,而是创建 List&lt;int&gt; 并将其用于 Contains,您的 LINQ 提供程序应该支持。 如果我按照您的描述填写列表,Linq 支持它很好。我的问题是我从 Json 帖子的字符串中获取此列表。所以我必须拆分和解析。我可以在没有模型的情况下执行此操作吗? @Philippe 是的,你可以。 var productMakerIdList=productMakerIds.Split(',').Select(int.Parse).ToList();

以上是关于C# - 在 Linq Where Any 语句中使用的要列出的字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在 linq 查询 c# 中的 WHERE 语句后嵌入动态 OR 条件

c# linq语句的where该怎样动态赋值?

c# linq 动态多条件查询语句的写法

LINQ 扩展方法 - Any() vs. Where() vs. Exists()

C# Linq ANY vs ALL - 性能 [关闭]

Linq