5

我正在处理由另一个系统维护的数据库,因此我无法对表进行任何重大更改。这个数据库中的表有很多字段(超过 30+),没有两个表具有相同的命名约定、类型或相同数量的字段。这些表也经常更改(添加、删除字段或更改它们的类型),更糟糕的是,新表也经常创建。现在我确实有一张可以严格输入的表,用作队列。

问题:

我必须从给定表名和该表中的某些列的表中获取数据。列名作为字符串提供。由于这些表经常更改,因此很难为每个表维护严格类型的实体。

我将如何以松散耦合但允许我使用这些表的方式设计我的类?

感谢您的帮助,如果我的解释很糟糕,我们深表歉意。

4

3 回答 3

1

我不确定您可以从不稳定的数据中得出什么样的业务逻辑。我的假设是您正在对与记录关联的元数据进行一些工作。使用数据的聚合(计数、平均值等)而不是实际数据。

我会使用 DataSet,使用通用 SQL 语句,例如:

SELECT * FROM {dynamic table name}
于 2012-11-14T04:14:16.780 回答
1

一种想法是使用带有表的SQL 管理对象 (SMO)来动态创建强类型。

Server srv = new Server(conn);
Database db = srv.Databases["AdventureWorks"];

foreach (Table table in db.Tables)
{
    Console.WriteLine(" " + table.Name);
    foreach (Column col in table.Columns)
    {
        Console.WriteLine("  " + col.Name + " " + col.DataType.Name);
    }
}

我已经以这种方式为数据访问层编写了单元测试生成器,您可以使用 DataTypes 列组成类,例如(在线查找更好的实现 - 在 C# 中):

Public Function SQLParameterType(ByVal ParameterDataType As String) As String

    ParameterDataType = ParameterDataType.ToUpper

    If ParameterDataType.IndexOf("NVARCHAR") > 0 Then
        Return "string"
    ElseIf ParameterDataType.IndexOf("VARCHAR") > 0 Then
        Return "string"
    End If

    Select Case ParameterDataType

        Case Is = "BIGINT"
            Return "Int64"
        Case Is = "INT"
            Return "Int32"
        Case Is = "SMALLINT"
            Return "Int16"

        Case Is = "BIT"
            If gIsVBdotNet Then
                Return "boolean"
            Else
                Return "bool"
            End If

        Case Is = "DATETIME"
            Return "DateTime"

        Case Is = "DATETIME2"
            Return "DateTime"

        Case Is = "SMALLDATETIME"
            Return "DateTime"

        Case Is = "MONEY"
            Return "single" 'float
        Case Is = "FLOAT"
            Return "single" 'float
        Case Is = "REAL"
            Return "double"
            'Case Is = "INT"
            '    Return "int32"
            'Case Is = "INT"
            '    Return "int32"
        Case Else
            Return "666"
    End Select

End Function

使用这个以模式中立的方式连接到数据库的简单 ORM,您可以将动态生成的类松散地耦合到 dB。.Net 4 中的新动态类型似乎是该应用程序的一个很好的多态数据类型候选者。

于 2012-11-14T04:58:43.157 回答
0

一种快速修复(不是解决方案)是使用像这样的代码生成实用程序,它会根据您的模板或数据表模式定义本身更新/创建您的类文件。通过一些工作,这可以通过自定义 MsBuild 任务在您的项目中完全自动化,该任务将在您构建项目时运行,并且您的文件将直接更新到您的解决方案文件夹中。

但最重要的是,当您的表定义更新时,它会在构建时破坏您的代码 - 向您显示由于表定义更改而必须修复的地方。为此,您的自定义 MsBuild 任务必须在主构建任务之前运行,如此处所述

这肯定会使您受益并使事情变得容易,因为我已经看到这样的设计使类似的项目受益,但最终“废话 - 废话”原则仍然盛行,因此上述“修复”只会治疗症状而不是原因可能是设计不佳并且缺乏对解决方案数据需求的抽象和分析。因此,您会得到一个需要重新编程才能重新配置的程序:)但对于 LOB 编程,这并不罕见:)

** 注意:如果您决定使用第一段中描述的设计,为了获得完整的解决方案,您可能需要一个额外的 MsBuild 任务,当架构更改。如果您需要更多信息,请在下方评论。

总结一下:当您按下 F5 在 Visual Studio 中构建您的解决方案时,您的所有类都将使用数据库中的最新定义神奇地更新。您还可以将其限制为Release仅在构建上发生,这样您就不会在开发时每次在Debug模式下构建时都完成此操作。

于 2012-11-14T04:44:31.270 回答