在dataTable中填充数据库中的所有数据并构建一个列表

时间:2015-10-02 07:58:22

标签: c# sql-server select datatable datarelation

我有两个这样的对象:

public class Place : ICloneable, IEquatable<Place>
{
    public string Name{ get; set; }
    public float longitude{ get; set; }
    public float latitude{ get; set; }
    public Horizon thehorizon  { get; set; }
    ...
}
public class Horizon
{
    public List<PointF> points{ get; set; }
}

在我的数据库中,我有2个表 - “地点”和“视野”,在视野中使用外键来了解这些点所属的位置。

所以这些地方的结构是:

  1. 名称-nvarchar - 主键
  2. 经度 - 真实
  3. 纬度 - 真实
  4. 和视野的结构是

    1. parent_key - nvarchar
    2. pointX - real
    3. poinY - real
    4. 我编写了下面的代码来选择所有数据并构建一个地方列表。它工作正常,但速度很慢。如果您有任何建议如何更快(或任何评论),请告诉我。

      DataTable TablePlaces;
      DataTable TableHorizons;
      
      public void init()
      {
          TablePlaces = new DataTable();
          TablePlaces.Columns.Add("Name");
          TablePlaces.Columns.Add("longitude");
          TablePlaces.Columns.Add("latitude");
      
          TableHorizons = new DataTable();
          TableHorizons.Columns.Add("parent_key");
          TableHorizons.Columns.Add("pointX");
          TableHorizons.Columns.Add("pointY");
      
          System.Data.DataSet DS = new DataSet();
          DS.Tables.Add(TablePlaces);
          DS.Tables.Add(TableHorizons);
          DS.Relations.Add(TablePlaces.Columns["Name"],
              TableHorizons.Columns["parent_key"]);
      }
      
      public List<Place> BuilsListPlace()
      {
          TableHorizons.Clear();
          TablePlaces.Clear();
          using (DbCommand Command = newConnectionNewCommand())
          {
              Command.CommandText = "SELECT * FROM places ORDER BY Name"
              fill(TablePlaces, Command);
              Command.CommandText = "SELECT * FROM horizons ORDER BY parent_key,pointX";
              fill(TableHorizons, Command);
      
              Command.Connection.Dispose();
          }
          return (from DataRow dr in TablePlaces.Rows
                  select newPlace(dr)).ToList();
      }
      
      void fill(TableDB t ,DbCommand Command)
      {
          using (var da = newDataAdapter())
          {
              da.SelectCommand = Command;
              da.MissingSchemaAction = MissingSchemaAction.Ignore;
              da.Fill(t);
          }
      } 
      Place newPlace(DataRow dr)
      {
          Place result = new Place();
          result.longitude=(float)dr["longitude"];
          result.latitude=(float)dr["latitude"];
          result.Name=(string)dr["Name"];
          result.theHorizon=newHorizon(dr.GetChildRows(dr.Table.ChildRelations[0]));
          return result;
      }
      
      Horizon newHorizon(DataRow[] Rows)
      {
          Horizon result = new Horizon();
          result.points = new List<PointF>();
          foreach(DataRow dr in Rows)
              result.points.Add(new PointF((float)dr["pointX"],(float)dr["pointY"]);
          return result;
      }
      

2 个答案:

答案 0 :(得分:0)

我找到了使用反射和放大器将datatable转换为list of objects的扩展程序。通用,但请记住,属性名称必须与数据表中的属性名称完全相同

希望有所帮助

public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
    try
    {
        List<T> list = new List<T>();

        foreach (var row in table.AsEnumerable())
        {
            T obj = new T();

            foreach (var prop in obj.GetType().GetProperties())
            {
                try
                {
                    PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                    propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
                }
                catch
                {
                    continue;
                }
            }

            list.Add(obj);
        }

        return list;
    }
    catch
    {
        return null;
    }
}

答案 1 :(得分:0)

我会尝试只选择你真正需要的东西。虽然你说你有大约1800个地方(这应该不是问题)...尝试使用以下

public IList GetPlaces()
{
  using (var conn = new SqlConnection("blahblahblah"))
  {
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT p.Name, h.pointX, h.pointY FROM places p LEFT OUTER JOIN horizons h ON h.parent_key = p.Name";

    DataTable tbl = new DataTable();

    using (var rdr = cmd.ExecuteReader())
      tbl.Load(rdr);

    return tbl.Rows
      .Cast<DataRow>()
      .Select(r => new
        {
          Name = r.Field<string>("Name"),
          HorizonX = r.Field<float>("pointX"),
          HorizonY = r.Field<float>("pointY")
        }).ToList();
  }
}

下面的“选择”部分返回的是匿名类型,而不是您要查找的类型。但是,从这里开始并将其转换为起诉Select / SelectMany a.s.o的课程应该不难。

请注意如何将数据返回到List 并不重要,但如何从数据库中读取非常重要。