Linq 过滤逗号分隔的数据

Linq 过滤逗号分隔的数据,linq,nhibernate,linq-to-nhibernate,Linq,Nhibernate,Linq To Nhibernate,我的站点有很多小部件,我正试图根据传入的url对它们进行过滤。假设小部件具有以下结构: public class Widget { public int Id { get; set; } public string Name { get; set; } public string Urls { get; set; } } 其中URL是小部件应显示的URL的逗号分隔列表,例如: /,/Blog/,/Blog/123,/News/* 新闻后的星号表示,只要传入的url以/N

我的站点有很多小部件,我正试图根据传入的url对它们进行过滤。假设小部件具有以下结构:

public class Widget {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Urls { get; set; }
}
其中URL是小部件应显示的URL的逗号分隔列表,例如:

/,/Blog/,/Blog/123,/News/*

新闻后的星号表示,只要传入的url以/News/开头,就会选择小部件

我如何修改下面的方法来根据上面的条件过滤小部件

public IList<Widget> GetWidgets(string url) {
    return _session
        .Where(w => w.Urls.Contains(url))
        .ToList();
}
public IList GetWidgets(字符串url){
返回会话
.Where(w=>w.url.Contains(url))
.ToList();
}

理想情况下,我希望使用linq查询,并且它只能访问数据库一次。我很感激你的帮助。谢谢

我认为SQL server不允许您在中使用逗号分隔的字段值。您需要类似的
(下面的SQL示例):

类似“%”的url\uURL\uURL%'


可以帮助您翻译
,如
Linq到NHibernate

我通过添加自己的通配符匹配生成器解决了这个问题。有关如何注册生成器的示例,请参见。这是发电机,以防有人感兴趣:

public class WildCardMatchGenerator : BaseHqlGeneratorForMethod {
    public WildCardMatchGenerator() {
        var methodDefinition = ReflectionHelper.GetMethodDefinition(() => WildCardMatchExtensions.WildCardMatch(null, null, ','));
        SupportedMethods = new[] { methodDefinition };
    }

    public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) {
        return treeBuilder.Equality(treeBuilder.MethodCall("[dbo].[WildCardMatch]", new[] {
            visitor.Visit(arguments[0]).AsExpression(),
            visitor.Visit(arguments[1]).AsExpression(),
            visitor.Visit(arguments[2]).AsExpression()
        }), treeBuilder.Constant(1));
    }
}
以及它调用的拆分函数(从):

最后,您需要上述UDF的C#实现:

public static class WildCardMatchExtensions {
    public static bool WildCardMatch(this string pattern, string input, char separator = ',') {
        foreach (var str in pattern.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries)) {
            if (Regex.IsMatch(input, Regex.Escape(str.Trim()).Replace("\\*", ".*")))
                return true;
        }

        return false;
    }
}
希望这有帮助

CREATE FUNCTION [dbo].[Split]
(    
    @RowData NVARCHAR(MAX),
    @Separator NVARCHAR(MAX)
)
RETURNS @RtnValue TABLE 
(
    [Id] INT IDENTITY(1,1),
    [Data] NVARCHAR(MAX)
) 
AS
BEGIN 
    DECLARE @Iterator INT
    SET @Iterator = 1

    DECLARE @FoundIndex INT
    SET @FoundIndex = CHARINDEX(@Separator, @RowData)

    WHILE (@FoundIndex > 0)
    BEGIN
        INSERT INTO @RtnValue ([Data])
        SELECT Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))

        SET @RowData = SUBSTRING(@RowData, @FoundIndex + DATALENGTH(@Separator) / 2, LEN(@RowData))
        SET @Iterator = @Iterator + 1
        SET @FoundIndex = CHARINDEX(@Separator, @RowData)
    END

    INSERT INTO @RtnValue ([Data])
    SELECT Data = LTRIM(RTRIM(@RowData))

    RETURN
END
public static class WildCardMatchExtensions {
    public static bool WildCardMatch(this string pattern, string input, char separator = ',') {
        foreach (var str in pattern.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries)) {
            if (Regex.IsMatch(input, Regex.Escape(str.Trim()).Replace("\\*", ".*")))
                return true;
        }

        return false;
    }
}