使用SQL表信息填充C#结构的有效/快速方法是什么?

时间:2012-01-08 03:24:07

标签: c# .net sql

简而言之:我有一些数据库表数据,我想填充c#结构。

例如:

struct Phone
{
    public int PhoneID;
    public string Number;
}
struct Patient
{
    public Phone WorkPhone;
}

SQL表看起来像这样:

Patient table:  
    Patient ID, Patient Name, etc.  
Phone table:  
    PhoneID, Number, Phone Type etc.  

基本上,结构是SQL表的镜像。

我有主键(PhoneID),我正在通过select语句。因此,我只会在患者的情况下检索一行,或者在电话表中最多检索5行(他们可以有WorkCellHome等。

我没有很好的方法可以轻松地将此表填充到结构中。我现在正在做的是一个接一个。每个患者可以看到数百个变量,这是一个非常繁琐且代码密集程度很高的过程。有没有办法,也许我可以在变量名中有一个变量,例如,如果列名是Phone,那么它将填充Phone变量。希望这是有道理的。

query = "SELECT * FROM Phone p WHERE p.StatusID = 'A' AND ObjectTypeID = 'PA' AND ObjectID = '" + PatientID.ToString() + "'";
SqlDataAdapter a1 = new SqlDataAdapter(query, dataConnection);
DataTable t1 = new DataTable();
a1.Fill(t1);
DataTableReader r1 = t.CreateDataReader();
//object value = null;
while (reader.Read())
{
    for (int i = 0; i < r1.FieldCount; i++)
    {
        if (!r1.IsDBNull(i))
        {
            if reader.GetValue(i)
            switch (r1.GetName(i))
            {
                case "PhoneID": { pr.HomePhone.PhoneID = (int)reader.GetValue(i); break; }
                case "PhoneTypeID": { pr.HomePhone.PhoneTypeID = (string)reader.GetValue(i); break; }
                case "ObjectID": { pr.HomePhone.ObjectID = (int)reader.GetValue(i); break; }
                case "ObjectTypeID": { pr.HomePhone.ObjectTypeID = (string)reader.GetValue(i); break; }

6 个答案:

答案 0 :(得分:4)

您可能需要NHibernateLightspeedEntity Framework之类的ORM。

如果他们有点矫枉过正,请查看一个像Massive这样的新型迷你ORM库。

答案 1 :(得分:2)

完全可能的ORM可能是不可能的,但您可以使用反射将数据表中的值映射到对象。或者,您也可以使用Automapper等内容。

答案 2 :(得分:2)

Dapper(stackoverflows轻量级对象映射器)似乎是一个强有力的候选者。到目前为止在一些项目中使用它并喜欢它。简单,快速,无痛。

除非结构是必需的,否则我建议切换到类。

http://code.google.com/p/dapper-dot-net/

答案 3 :(得分:2)

您可以使用词典。逻辑是:

while (reader.Read())
            {
                Dispute disp = new Dispute();
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    if (!reader.IsDBNull(i))
                    {
                        //Getting a property name associated to filed name
                        string mappedProperty = dataMapping[reader.GetName(i)];
                        //Getting handle to the property
                        PropertyInfo fld = typeof(Dispute).GetProperty(mappedProperty);
                        //Setting property value to field value
                        fld.SetValue(disp, reader.GetValue(i));
                    }
                }
            }

在这种情况下,您只需要一个字典dataMapping,它将您的字段名称与对象中的属性相关联。我就是这样做的。它可以处理任何字段结构,几乎没有修改 代码 - 只需要修改字典。

更好的方法是将其反转并将对象结构用作驱动程序。

  1. 使用fieldName,filedValue
  2. 填写中间词典
  3. 将其传递给具有需要使用值
  4. 填充的对象的函数
  5. 遍历所有对象属性并使用反向dataMapping字典分配值。
  6. 在这种情况下,例程基本上变为与对象类型无关,并且仅分配找到的字段的值。它也可以作为方法抽象为基类,并继承到实际的类。

答案 4 :(得分:1)

一般来说,可变结构是一个非常糟糕的主意。

您应该考虑使用许多可用的ORM中的一种,它专门用于此目的。

如果你一心想做自定义的东西,那么一般的想法就很简单了。

  1. 使用反射检查给定类型
  2. 使用动态编译或表达式
  3. 将类型字段/属性绑定到数据读取器字段名称
  4. 魔术发生

答案 5 :(得分:1)

添加@Bevan提供的答案我会在列表中添加实体框架4.1(EF 4.1与其他版本大不相同),My Generation包含示例模板,如Gentle.NET或Code Smith。 / p>