【问题标题】:Data table retrieval using column name or integer使用列名或整数检索数据表
【发布时间】:2018-11-13 18:44:05
【问题描述】:

所以,只是在这里寻找一个一般的经验法则,似乎找不到一个合法的方法来推进。我经常看到。

基本上你有这样的东西:

DataTable dt = new DataTable();
dt blah blah blah .Fill

现在访问:

dt.Rows[i]["ColumnName"].ToString();
dt.Rows[i][ColumnInteger].ToString();

所以问题是,我看到了两者的优点。如果我们一直使用整数,那么有一天更改表中的列名将没有任何效果。在同一方面,从可读性方面来看,使用列名肯定更容易。或者,从性能的角度来看,也许有理由选择其中一个。

所以说真的,你们都看到了一致的做法?

【问题讨论】:

    标签: c# sql datatable


    【解决方案1】:

    所以说真的,你们都看到了一致的做法?

    它们的存在都是有原因的,当另一个不存在时,它们都有用。您将始终与 SQL 领域中的表紧密耦合。如果您想通过列索引或字符串耦合它,这只是您的选择。

    实际上,我从未设计过使用数据表的系统。我有一个强类型面向对象的语言,所以我选择在通用数据容器上使用对象。

    ORM 框架,如Entity Framework (microsoft)DapperNHibernate 等,允许您的数据库行(XML 节点、Json 对象等)表示一个 .net 对象(已定义、匿名,有时还包括元组) .目标是从存储系统系统中获取数据并将您的请求转换为类。检索数据后;

    数据表可能如下所示:

    [1]Id     [2]FirstName         [3]LastName
    (int)     (string)              (string)
    --------------------------------------------
    1         Erik                  Philips
    

    所以计算一个全名变成如下代码:

    var fullName = $"{dt.Rows[i][2].ToString()} {dt.Rows[i][3].ToString()}";
    

    var fullName = $"{dt.Rows[i]["FirstName"].ToString()} {dt.Rows[i]["LastName"].ToString()}";
    

    它的作用是什么,但是应该封装面向对象语言中的逻辑。使用 ORM,您的数据是通过表示数据访问的类请求的,并被配置为获取数据并映射它(我不会详细介绍细节)。首先,您首先创建一个POCO

    public class Person
    {
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
    }
    

    然后您通过数据访问类请求它们;

    实体框架(DbContext)

    var person = DbContext.Persons.FirstOrDefault(p => p.id == 1);
    // OR
    var person = DbContext.Set<Person>().FirstOrDefault(p => p.id == 1);
    

    Dapper:(*我没有使用过 Dapper,所以这在技术上可能是错误的,但你明白了)

    var person = connection.Query<Person>("Select * FROM CUSTOMERS WHERE Id = 1").FirstOrDefault()
    

    NHibernate:

    var person = session.Get<Person>(Id);
    

    在所有这些实例中,您都会返回一个 Person 类/对象。现在我们可以封装业务逻辑(我们需要有一种一致的方式来向我们的数据消费者表示“全名”)。

    public class Person
    {
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public DateTime BornOn { get; set; }
      public boolean IsMarried { get; set; }
      public string FullName 
      {
        get 
        {
         return $"{FirstName} {LastName}";
        }
      }
    }
    

    但这就是这一切的主要目标吗?

    在我个人看来,这一切的目的是帮助开发人员编写好的代码,其中包括(与我将评论的问题相关的项目);

    使用S.O.L.I.D. Principles:

    单一单一责任原则

    // What else could this class possibly be used for?
    public class Person ....
    

    Writing readable code with as little documentation as possible.

    var tom = dbContext.Persons.FirstOrDefault(p => p.FirstName == "Tom");
    
    if (tom.IsMarried) ...
    
    if (tom.BornOn > DateTime.Now) ...
    

    【讨论】:

    • 补充@Erik 在最后一段中所说的话:我喜欢使用实体框架来处理对象。
    • 这个答案也是如此。明智的反应。我认为下面的帖子在这种情况下效果更好。但是明白你在说什么。我已经标记了一个答案,但请随时发布任何小样本,我相信其他人也想知道这一点。
    • @ErikPhilips 华丽的例子。谢谢你编辑。我认为在大多数情况下,我会关注这里发生的事情。那么从比较的角度来看,你的例子是为了可读性和遵循 OOP 实践吗?就像当您展示从数据表访问时一样,我可以很快看到与深思熟虑的方法相比,它看起来更丑陋和令人困惑,但这就是主要目标吗?
    • 所以两周后的实体框架与我之前的数据访问方法相比就像一场梦。非常感谢人!你对帖子的更新太棒了。再次感谢!
    • @MikeCMR 很高兴听到它对您有用。请注意,就像任何框架一样,他们每个人都有优点和缺点。使用 EF,您可以获得 serialization problems 等等等等。
    【解决方案2】:

    这不会回答“什么是正确的方法”的问题,但如果您想在仍然使用索引的同时保持可读性,您可以创建一个enum

    enum ColumnNames
    {
      FirstName = 1,
      LastName =2, 
    }
    
    dt.Rows[i][(int)ColumnNames.FirstName].ToString();
    

    【讨论】:

    • 爱它,使用它,这是正确的方法哈哈。两全其美。
    猜你喜欢
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2020-05-07
    • 2022-06-26
    • 2019-09-17
    • 2023-01-20
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多