带参数化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();