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

时间:2012-01-17 19:21:44

标签: .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的有用应用。因此,问题基本上是:这种方法可能产生哪些缺点和/或问题?你会推荐(反对)使用这种方法吗?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:1)

好吧,如果有人在这么久之后读到这个......

如果您的公司使用SQL Server,它们通常会保留在SQL Server中,所以我认为如果这是您的环境,并且可能仍然保留,那么这是一个好主意。我已经查看了Entity Framework和NHibernate,发现它们都非常复杂 - 只需几个方法,SQL Server和原始ADO就非常强大,并且在应用程序和数据库层之间弹跳数据结构实际上是用户定义的表变量的明智之举。 上面提到的OOP vs DBA是完整的 - 如果你正在开发数据库驱动的应用程序,你应该了解数据库以及应用程序层的OO架构,否则你就有了头脑。