C# 什么策略:存储在数据库中的自定义LINQ或SQL查询

C# 什么策略:存储在数据库中的自定义LINQ或SQL查询,c#,.net,asp.net-mvc,entity-framework,linq-to-entities,C#,.net,Asp.net Mvc,Entity Framework,Linq To Entities,我正在开发的一个应用程序广泛使用Linq。它是多租户的,因此不同的客户将其所有数据存储在同一个数据库中 一些客户想要定制报告。理想情况下,这些自定义报告的定义将存储在数据库中,与客户相对应,因为将这些报告硬编码到主代码中是不切实际的(很快就会失控) 过去我通过存储SQL字符串解决了这个问题,然后使用context.SqlQuery(myReportSQL)对这些字符串进行计算。它工作得很好 两个想法: 目前,客户无法编辑SQL字符串。它在内部进行管理,以避免运行错误类型的查询。您建议如何向客户开

我正在开发的一个应用程序广泛使用Linq。它是多租户的,因此不同的客户将其所有数据存储在同一个数据库中

一些客户想要定制报告。理想情况下,这些自定义报告的定义将存储在数据库中,与客户相对应,因为将这些报告硬编码到主代码中是不切实际的(很快就会失控)

过去我通过存储SQL字符串解决了这个问题,然后使用
context.SqlQuery(myReportSQL)
对这些字符串进行计算。它工作得很好

两个想法:

  • 目前,客户无法编辑SQL字符串。它在内部进行管理,以避免运行错误类型的查询。您建议如何向客户开放?查询生成器界面(对插件v欢迎有什么建议吗)?只允许SELECT语句的东西

  • 一个更好的方法是使用LINQ到EF查询,因为:更容易确保它是一个仅选择的查询,我可以在最后链接其他位置,以确保它们只获得正确的数据,并且更具可读性

  • 那么,对于选项2,如何将其存储在数据库中,然后有效地“评估”它呢


    我见过动态LINQ库,它在一定程度上有所帮助,但我担心它会变得陈旧,可能会被删除/不支持EF6等。

    如果要以任何格式存储查询,我会选择SQL,因为这是执行任何db查询的最终形式,它是人类可读的,它可以很容易地以纯文本格式存储。当然,这正是数据库对存储过程和视图定义所做的,因此,您也可以简单地使用数据库提供的功能,并处理存储过程或视图定义

    根据应用程序的使用环境,现有的数据库报告工具(如MS SSRS)将利用数据库安全和查询功能,并提供部署平台

    为了回答如何打开用户修改查询的问题,需要考虑各种问题:

    • 您的用户最喜欢以什么形式修改查询(例如SQL、图形查询生成器等)
    • 您需要实施哪些安全限制以确保用户只能访问适当的DML命令和授权数据(同样,数据库提供了安全功能,因此请确保您没有重新发明轮子)
    • 您需要什么版本控制功能来允许用户自定义查询而不影响其他用户

    然后决定您的方法并设计一个解决方案。

    在多租户中,如何处理动态查询的安全性是一个困难的部分

    我将从表值函数开始,在表值函数中为客户ID硬编码一个参数

    使用它来构建一些直接表和一些公共联接


    视图允许安全性,但不幸的是,不允许您传递参数(我知道),以便多个客户可以使用同一视图。您可以有一个视图,为每个客户制作一个版本

    我使用动态linq也有类似的用途,但同样担心没有被构建到框架中。其想法是存储片段,而不是一个大型查询。例如,如果要显示父关系中的列,可以使用“parent.column”作为该列的表达式。在这方面,它的编写和维护要比SQL简单得多,因为您不必编写所有的连接等

    我们还有一个谓词的概念,在这里存储一个表达式和一个运算符,并传入一个值。例如,存储“Parent.Column”和“Equals”,并在字典中传入值。e、 g.字典[“parentColumn”]


    既然您提到这将用于报告,您是否考虑过使用SSRS(SQL Server reporting Services),它允许您定义数据源并让您的业务用户创建自己的报告?您可以通过以不同的方式定义数据源来处理多租户。

    我想到了另一个想法:以某种JSON格式存储查询。有没有我应该遵循的标准。如果您向客户开放,那么您会保护客户不被其他客户获取数据?二号。客户将如何建立LINQ运行时间?1。没错,这就是问题所在!必须非常仔细地分析/检查它。一点也不喜欢这个。一个解决方案是让他们从一个预定义的查询中进行查询,该查询只包含允许他们查看的数据。2-好吧,我想这是不可能的。因此,我的问题在这里。也许我想要的是内部解析的linq风格的语法。我不敢相信我会这么说-但是你考虑过实体SQL吗?这里的其他答案都很有用,但对我来说这是最好的方法。它提供了片段的安全性,这些片段可以由客户指定,然后以安全的方式连接在一起。它自然会产生一个用户界面,您可以从下拉菜单或拖放菜单中选择字段和谓词等等。