3

我正在尝试执行以下操作:

var query =
    (from a in session.Query<A>()
    where a.BasicSearch(searchString) == true
    select a);

但它一直给我这个异常“System.NotSupportedException”!

知道如何解决这个问题吗?

4

4 回答 4

7

不能在 LINQ 查询中使用用户定义的函数。NHibernate linq 提供程序不“知道”如何将您的函数转换为 SQL。

LINQ to NHibernate 的工作原理是检查您在运行时提供的 LINQ 表达式,并将在此表达式树中找到的内容转换为正则 SQL 表达式。这是一篇了解表达式树背景的好文章:http: //blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx

但是,您可以使用此处讨论的技术以另一种方式重用此类谓词。(我不确定这是否适用于 NHibernate。)如果它有效,它看起来像这样:

// this could be a static method on class A
public static Expression<Func<A, bool>> BasicSearch(string criteria)
{
    // this is just an example, of course
    // NHibernate Linq will translate this to something like 
    // 'WHERE a.MyProperty LIKE '%@criteria%'
    return a => criteria.Contains(a.MyProperty); 
}

用法:

from a in Session.Query<A>().Where(A.BasicSearch(criteria))

更新:显然 NHibernate 会有问题。请参阅此博客文章了解应该可以使用的版本

于 2012-12-03T08:28:36.703 回答
1

可以调用您自己的和 SQL 函数,但您必须为它们制作一个包装器,以便 NHibernate 知道如何将 C# 转换为 SQL。

这是一个示例,我编写了一个扩展方法来访问 SQL Server 的NEWID()函数。您将使用相同的技术来访问数据库服务器上的任何其他功能,无论是内置的还是用户定义的。

于 2012-12-03T09:45:11.230 回答
1
于 2012-12-03T18:03:21.747 回答
0

声明一个BasicSearch扩展方法。假设您的 udf 在 dbo 上:

using NHibernate.Linq;

...

public static class CustomLinqExtensions
{
    [LinqExtensionMethod("dbo.BasicSearch")]
    public static bool BasicSearch(this string searchField, string pattern)
    {
        // No need to implement it in .Net, unless you wish to call it
        // outside IQueryable context too.
        throw new NotImplementedException("This call should be translated " +
            "to SQL and run db side, but it has been run with .Net runtime");
    }
}

然后在您的实体上使用它:

session.Query<A>()
    .Where(a => a.SomeStringProperty.BasicSearch("yourPattern") == true);

请注意,尝试使用它而不在其使用中引用实体将导致它使用 .Net 运行时进行评估,而不是将其转换为 SQL。

使这个BasicSearch例子适应它必须处理的任何输入类型。您的问题是直接在实体上调用它,这不允许您的读者知道它需要运行多少列以及使用哪些类型。

于 2017-02-20T14:25:26.340 回答