动态构造对数据库的查询

时间:2016-01-09 09:52:10

标签: f#

我目前正在使用FSharp.Data.SqlClient,但我对任务的任何解决方案感兴趣。

我有一个Web客户端,后端用F#编写。在Web客户端中,用户可以设置10-20个过滤器并向我的F#后端发出GET请求。 URL如下所示:

# work
img_url = 'http://img.mangastream.com/cdn/manga/51/3140/006.png'
img_filename = 'my_img.png'
urllib.request.urlretrieve(img_url, img_filename)

此网址中的任何数字都是过滤条件。如果相应过滤器的值为零,则相应字段上没有过滤器。

现在我需要在后端构建SQL查询。虽然可能的过滤器数量为3-4,但我使用的是模式匹配:

http://mybackend.com/get/1/0/34/ ....

但是当滤波器的数量大于3-4时,很难为所有参数组合编写模式匹配。

我认为我需要动态构建SQL查询。 URL中的每个非零参数都必须将type GetEObyOrg1Org2AsutpParent = SqlCommandProvider<"SELECT * FROM ITEM WHERE ORGID1 = @org1 AND ORGID2 = @org2 AND ASUTPID = @asutp AND PARENTAUTOINCID = @parent", "name=MobileConnectionProvider", ResultType.Tuples> type GetEObyOrg1Org2Org3AsutpParent = SqlCommandProvider<"SELECT * FROM ITEM WHERE ORGID1 = @org1 AND ORGID2 = @org2 AND ORGID3 = @org3 AND ASUTPID = @asutp AND PARENTAUTOINCID = @parent", "name=MobileConnectionProvider", ResultType.Tuples> match (asutpid, orgId1, orgId2, orgId3) with | "0", _, "0", "0" -> let cmd = new GetEObyOrg1Org2AsutpParent() cmd.Execute(org1 = orgId1, parent = parentAid) | "0", _, _ , "0" -> let cmd = new GetEObyOrg1Org2Org3AsutpParent() cmd.Execute(org1 = orgId1, org2 = orgId2, parent = parentAid) 表达式添加到SQL语句中。但我不能这样做:

AND Field = Value

type GetEObyOrg1AsutpParent = SqlCommandProvider<Query, "name=MobileConnectionProvider", ResultType.Tuples> 参数是这个表达式必须是文字,而我不能用语法构造文字表达

Query

在我的案例中,最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

我认为在这样的情况下,核心库的SqlDataConnection类型提供商可能更适合。然后,您应该能够使用标准IQueryable操作动态添加其他WHERE子句,例如:

type MyDb = SqlDataConnection<...>
let items = MyDb.GetContext().Item
let q1 = if asutpid = 0 then items else items.Where(fun i -> i.Asutpid = asutpid)
let q2 = if orgId1 = 0 then q1 else q1.Where(fun i -> i.OrgId1 = orgid1)
...