.net - 使用 CLR UDT 作为 SQL Server 存储过程参数

标签 .net sql-server stored-procedures clr

我一直在阅读有关 SQL Server 中 CLR 集成的一些资料(我使用的是 2008 R2,但我认为这与问题无关),并碰到了 CLR UDT 的主题。看完之后,我发现大多数人认为它们是邪恶的,建议不要使用它们,甚至暗示它们没有任何实际应用。但是,我发现关于 CLR UDT 的每一次讨论都围绕着将它们用作列类型来将对象存储在数据库中,但我找不到任何关于严格使用它们来简化应用程序-数据库通信的信息。

在从事许多项目之后,我仍然需要找到一个对我有吸引力的解决方案的领域之一是应用程序层和数据层之间的通信,因此我总是对新方法感兴趣。我通常采用的方法是通过存储过程处理所有数据访问。然而,有一件事让我很烦恼,那就是必须在很多地方维护一个对象的属性列表和相应的表列。例如,如果我有一个包含 20 个属性/列的 Product 数据对象,我必须在几个地方维护这个属性列表:

  • (1x) 数据库表
  • (3x) 创建/检索/更新存储过程的主体
  • (3x) 创建/检索/更新存储过程的参数列表
  • (3x) 调用存储过程的应用程序代码(这里是对象关系映射)
  • (1x) 数据对象类定义

在这里,我看到了 CLR UDT 的潜在非恶意应用程序:使用 CLR UDT,我可以使用对象在应用程序和数据库之间进行通信,并将对象关系映射移动到存储过程。这是我的意思的一个例子:

产品更新存储过程:

CREATE PROCEDURE crudProductUpdate
    @Product udtProduct
AS
    UPDATE Products
    SET Name = @Product.Name,
        Manufacturer = @Product.Manufacturer,
        Price = @Product.Price,
        ...
    WHERE SKU = @Product.SKU

产品更新申请代码:

void Update()
{
    using (SqlCommand cmd = new SqlCommand("crudProductUpdate", this.DB)
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@Product", this);
        cmd.ExecuteNonQuery();
    }
}

使用这种方法,我将能够减少需要维护属性/列列表的地方:

  • (1x) 数据库表
  • (3x) 创建/检索/更新存储过程的主体(这里是对象关系映射)
  • (1x) 数据对象类定义

在理论上,这似乎是一个无需动脑筋的事情,但我敢肯定我是目光短浅,我忽略了这种方法的一些缺点,以及 CLR UDT 的潜在有用应用。所以,问题基本上是:这种方法可能会产生什么缺点和/或问题?您会推荐(反对)使用这种方法吗?

最佳答案

我可以看到至少两个间接缺点:

  • 它确实将整个应用程序与 SQL Server 联系在一起。如果将来有一天,您想要更改持久层(例如 Oracle、PostgreSQL、MySQL 等),您将有很多工作要做。
  • 两个世界的集成:OOP 与关系在 OOP 开发人员与 DBA 的集成方面提出了艰巨的挑战。简单地说,OOP 开发人员不喜欢 SQL,而 DBA 不喜欢 C#。因此,您可能很难找到具有正确关系 + OOP 能力的合适人选,甚至找不到解决它的意愿。我个人认为这是不幸的,但这往往是企业界的现实。如果您是唯一维护该应用程序的人,那不是问题。

否则,我认为这是一个不错的设计选择。

请注意,您也可以使用 SQL 2008 Table-Valued parameters with user-defined table types对于不使用 CLR/SQL Server 集成工具的相同类型的结果。

PS:你也可以使用代码生成器来完成所有这些,这也会减少要做的工作。

关于.net - 使用 CLR UDT 作为 SQL Server 存储过程参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8900420/

相关文章:

c# - 与 ConcurrentDictionary<Tkey, TValue> 一起使用时 C# LINQ OrderBy 线程安全吗?

c# - 在流畅的 nHibernate 中将平面 View 映射到类层次结构

c# - 我可以依赖哪些版本的 .NET Framework?

SQL Server : Joins,重复记录和联合

sql-server - Powershell SQLServer 模块

c# - 处理存储过程

c# - 如何创建一个 "Processing"页面?

sql-server - 附加数据库时出现 SQL Server 错误 5123

c# - 如何将选择的存储过程映射到 EF 3.5 中的实体?

c# - 是否有将 T-SQL 存储过程转换为 C# 的工具?