C# NHibernate Linq:如何在整数类型上使用StartsWith

C# NHibernate Linq:如何在整数类型上使用StartsWith,c#,.net,linq,nhibernate,C#,.net,Linq,Nhibernate,我想执行这样的查询,但失败了: session.Linq<Product>().Where(p=>p.Id.ToString().StartsWith("123")) session.Linq().Where(p=>p.Id.ToString().StartsWith(“123”)) 有解决办法吗?我更喜欢使用LINQ。。。也许有一种简单的方法可以扩展linq提供程序 我使用的是NHibernate2.1.2 编辑:是的,它失败了,因为NHIbernate.Linq没有处理

我想执行这样的查询,但失败了:

session.Linq<Product>().Where(p=>p.Id.ToString().StartsWith("123"))
session.Linq().Where(p=>p.Id.ToString().StartsWith(“123”))
有解决办法吗?我更喜欢使用LINQ。。。也许有一种简单的方法可以扩展linq提供程序

我使用的是NHibernate2.1.2

编辑:是的,它失败了,因为NHIbernate.Linq没有处理ToString()

我同意评论中的观点,如果需要对产品Id字段进行字符串比较,那么它应该是一个
char
varchar
字段开始

产品Id中的位数是否为常量?在这种情况下,您可以编写如下内容:

session.Linq<Product>().Where(p=>p.Id >= 10000 && p.Id < 20000)
但是,我认为NHibernate2.1.2的Linq提供程序无法将.Net数学函数映射到相应的t-SQL函数。您可以尝试一下:

session.Linq<Product>().Where(p => p.Id / Math.Pow(10, Math.Floor(Math.Log10(p.Id))) == 1)
session.Linq().Where(p=>p.Id/Math.Pow(10,Math.Floor(Math.Log10(p.Id)))==1)

查询可能会失败,因为NHibernate不知道如何将ToString()(或各种解析)转换为CAST/CONVERT方法


我同意Elian和SLaks的观点-如果您需要产品ID中的单个“字符”,那么这个ID应该是一个varchar。没有真正优雅的方法可以让这个查询以其他方式工作;如果它是一个字符串,StartsWith()函数将被转换成类似于“x%”的
ProductId条件。

如果升级到NHibernate 3,它可以识别类似
p.Id.NumberStartsWith(1)
的表达式(这将包装作为此问题答案的任何建议方法)

这需要做一点工作,但一旦完成,客户端代码就会非常漂亮


另外,您将有很多乐趣:-)

如果您确实需要这样做,您可能需要创建一个并行列,它可能是您的键的字符串版本。使用NHibernate拦截器、数据库触发器或许多其他选项可以保持字段的更新和同步,而不会弄乱代码


我想我会避免这样做,但这是你可以选择的一种方式。

这是一个标志,表明你的字段应该是字符串。只是出于好奇,你到底为什么要寻找“以1开头”的Id值?@StriplingWarrior,可能是:有一个用户在文本框中键入“1”,并准备键入下一个数字,但是在这些按键之间-开发人员希望在数据库中运行一些IO。@David B:是的,就是这样,多间隔代码甚至可以使用索引(我不知道特定的DB服务器是否可以)然而,在最后一段代码中使用索引需要不切实际的数学知识。这似乎是最容易做到的事情,但与其在拦截器中更新paralel列,我只需在第一列的setter中更新它。实际上,您不需要单独的DB列:您可以使用公式。缺点是它不能被索引。@Diego Mijelshon:这对我来说是最好的解决方案,谢谢,我不知道NHibernate公式取决于行数,特别是对于“键入时查找”的内容,索引确实非常有用。这是一个非常好的建议,但该项目已经投入生产,现在更改NHibernate版本是不明智的
(Product.Id / POWER(10, FLOOR(LOG10(Product.Id))))
session.Linq<Product>().Where(p => p.Id / Math.Pow(10, Math.Floor(Math.Log10(p.Id))) == 1)