带参数化IN子句的FluentNHibernatefilter

在Fluent NHibernate中,是否可以将参数添加到List类型的filter中,以便过滤条件生成WHERE SomeColumn IN (@x, @y, @z)

我的用例是根据发票的ID和发票行号列表获取发票及其行的子集。 我想急切地在与发票相同的往返途中获取线路。 我假设它是这样做的,但我找不到参数类型的正确类型声明:

域对象:

 public class Invoice { public int Id {get;set;} public List Lines {get;set;} } public class InvoiceLine { public int Id {get;set} public int LineNumber {get;set;} } 

映射:

 public class InvoiceMap : ClassMap { public InvoiceMap() { Id(x => x.Id); HasMany(x => x.Lines).ApplyFilter(); } } public class InvoiceLineMap : ClassMap { public InvoiceLineMap() { Id(x => x.Id); Map(x => x.LineNumber); } } 

filter定义:

 public class OnlyLinesWithNumbersFilter : FilterDefinition { public OnlyLinesWithNumbersFilter() { WithName("OnlyLinesWithNumbers"); WithCondition("LineNumber IN (:LineNumbers)"); AddParameter("LineNumbers",?? What to put here ??); } } 

查询:

 var filterName = "OnlyLinesWithNumbers"; session.EnableFilter(filterName).SetParameterList("LineNumbers", new[] {1,2,3}); var query = session.QueryOver() .Where(i => i.Id == 42) .Fetch(i => i.Lines).Eager .TransformUsing(new DistinctRootEntityResultTransformer()); var result = query.SingleOrDefault(); session.DisableFilter(filterName); 

就拿-2

 InvoiceLine invoiceLineAlias = null; var list = session.QueryOver() .Where(x => x.Id == 1) .JoinQueryOver(x => x.Lines, () => invoiceLineAlias, JoinType.LeftOuterJoin) .WhereRestrictionOn(() => invoiceLineAlias.LineNumber) .IsIn(new List { 1, 2, 3 }) .List(); 

制作sql:

 SELECT this_.Id as Id2_1_, invoicelin1_.Invoice_id as Invoice3_3_, invoicelin1_.Id as Id3_, invoicelin1_.Id as Id3_0_, invoicelin1_.LineNumber as LineNumber3_0_ FROM "Invoice" this_ left outer join "InvoiceLine" invoicelin1_ on this_.Id=invoicelin1_.Invoice_id WHERE this_.Id = @p0 and invoicelin1_.LineNumber in ( @p1, @p2, @p3 ); @p0 = 1 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)], @p2 = 2 [Type: Int32 (0)], @p3 = 3 [Type: Int32 (0)] 

你可以写

 var list = session.QueryOver() .WhereRestrictionOn(p => p.SomeColumn) .IsIn(someList) .List(); 

要将NHibernate Filters与数组一起使用,请将NHibernateUtil.Int32放在AddParameter方法中,所以这样做:

 public class OnlyLinesWithNumbersFilter : FilterDefinition { public OnlyLinesWithNumbersFilter() { WithName("OnlyLinesWithNumbers"); WithCondition("LineNumber IN (:LineNumbers)"); AddParameter("LineNumbers", NHibernateUtil.Int32); } } 

当您启用filter时,在SetParameterList中设置一个数组

 int[] lines = new int[] {1, 2, 3}; session.EnableFilter("OnlyLinesWithNumbers").SetParameterList("LineNumbers", lines); 

在我的测试中,我使用NHibernate 4.0.0.400

我认为这是正确的语法,我只是把它写在了我的头顶。 🙂

 InvoiceLine invoiceLine = null; var result = session.QueryOver() .Where(x => x.Id == 42) .JoinQueryOver(x => x.InvoiceLines, () => invoiceLine) .WhereRestrictionOn(x => x.ItemNumber) .IsIn(new[] {1, 2, 3}) .SingleOrDefault();