Linq to SQL WHERE IN语句返回的结果超出了预期

本文关键字:结果 返回 SQL to WHERE IN 语句 Linq | 更新日期: 2023-09-27 18:25:58

好的,我正在尝试制作一个局部视图和控制器,其工作是为当前在父视图中查看的任何产品选择并显示配件列表。

我再次工作的数据库将这些信息存储在一个字段中,该字段格式为逗号分隔列表,如下所示:

productnr,productnr2,productnr3,productnr4

因此,我使用以下代码来检索此列表,并使用它来运行等效于SQLWHERE IN语句的语句:

[ChildActionOnly]
public ActionResult _ListAccessories(string Artnr)
{
    var List = (
        from ArtTbl in db.ArtTbl
        where ArtTbl.ArticleNr == Artnr
        select ArtTbl.AccessoryList)
        .SingleOrDefault();
    var AccList = customFunctions.Accessories(text);
    var AccQuery = 
        from Art in db.ArtTbl
        where AccList.Contains(ArtTbl.ArticleNr)
        select new AccessoryList
        {
            Artnr = ArtTbl.ArticleNr,
            Name = ArtTbl.Namefield_1,
        };
    return PartialView(AccQuery);
}

AccList变量中的函数将第一个字符串转换为下面的结果。我这样做是因为我看到的所有示例都使用了这样的语法,该函数似乎可以正常工作,正如我测试的那样,将其作为viewBag发送到视图,只是为了检查它是否正确:

"productnr", "productnr2", "productnr3", "productnr4"

这也是AccessoryList模型的样子,只是一个非常简单的模型:

public class AccessoryList 
{
    public string Artnr { get; set; }
    public string Name { get; set; }
    public AccessoryList()
    {
    }
}

现在这个代码有效,但问题是它太慷慨了,如果我在列表中有一个产品编号,上面写着"AP500W",那么它也会返回"AP500"或仅返回"500"。这是一个问题,因为它应该只返回完全匹配的结果。

Linq to SQL WHERE IN语句返回的结果超出了预期

出现问题的原因开始和结束于:

我再次使用的数据库将此信息存储在字段中格式化为逗号分隔列表

LINQ正在将其转换为SQL语句,该语句将整个字段值视为单个实体,因为它单个实体。当计算Contains()时,它只是在寻找匹配的子字符串值。这就是为什么AP500500AP500W匹配。

由于您确实在尝试执行WHERE IN (...)的等效操作,因此需要将MVA(多值属性)转换为一组不同的值。

该查询适用于您发送单个字符串值的视图包:的示例

"productnr", "productnr2", "productnr3", "productnr4"

您的数据库值实际上是单个字符串值:

"productnr, productnr2, productnr3, productnr4"

区别很微妙,但非常重要。请注意,在第二个示例中,只有一个数据字符串用作单个值。

丹尼斯,

我知道以下内容不会完全回答你的问题。然而,它可能会让你更接近一个解决方案。在你的例子中,你说:

where AccList.Contains(ArtTbl.ArticleNr)

这就是为什么在结果集中获得通配符结果的原因。缓解这种情况的一种方法是只检查结果字符串的前部:

where AccList.StartsWith(ArtTbl.ArticleNr)

你甚至可以看看(虽然我确信这不会起作用):

where AccList.Any(x => x.StartsWith(ArtTbl.ArticleNr))

在上面的情况下,你会得到'AP50', 'AP500'等的结果。可能值得进一步研究(我现在不在编译器,所以无法验证上面是否按预期工作:-))。