【问题标题】:.NET Core 2.0 Strongly Typed DataRows.NET Core 2.0 强类型数据行
【发布时间】:2018-02-04 01:16:03
【问题描述】:

有没有办法在不使用 EF 或任何 ORM 的情况下在 C# .NET Core 2.0 中强类型化 DataRow?我在 vb.net 上使用了数据集,但它似乎还不可用。此外,似乎 SqlCommandBuilder 也不可用。

我在 vb.net 中使用过类似的东西:

Public Sub EntityToDataSet(ByRef entity As User, ByRef dataset As MyDataSet)
Dim dr As MyDataSet.UsersRow
dr = dataset.Users.NewUsersRow()
dr.Address = entity.Address
dr.Name = entity.Name
_dataAdapterUsers.Update(dataSet)
End Sub

如您所见,数据集提供了强类型行。我希望能够在 .NET Core 上做这样的事情。

【问题讨论】:

  • 为什么不能使用 EF 或其他 ORM?
  • 这是大学作业
  • 类型化数据集?
  • 数据库 就其本质而言,是强类型的(所有列都有类型)。如果您必须进行自己的对象映射...这不是问题,我们可以“修复”。
  • @Matias 大学是否需要强类型 DataRows 作为作业/项目的一部分?

标签: c# strongly-typed-dataset .net-core-2.0


【解决方案1】:

即使strongly typed DataSets、DataRows 等可以使用 .NET Core Stack 和 ADO.NET which they are not,我想你会发现今天在 .NET Core 社区中很少使用 DataRow 或DataSet 根本就不是作为强制强类型的手段,for example。 ADO.NET 为其一些关键对象(如 DataTable、DataRow、Dataset)提供开箱即用的“强类型”概念是一种老派的心态。如果您在当今时代想要一个强类型的解决方案,您只需定义您的类型并在尝试不正确的类型转换时抛出异常,或者甚至不抛出异常,C# 将为您抛出无效的转换异常。

我认为说使用强类型 DataRow/DataSet 实现让人想起您可能在 1999-2005 年使用 ASP.NET Web 窗体堆栈执行的实现也是有道理的。如果我没记错的话,ADO.NET DataTable 和 DataSet 具有这些开箱即用的强类型功能,开发人员会使用这些功能。但是今天,最佳实践总是让事情变得非常简单和干净,没有微软过去提供的开箱即用的魔法,这种魔法几乎总是导致单一的、难以维护的软件架构。

我相信下面的代码是一个“强类型”解决方案,使用 .NET Core 2.0、ADO.NET 而不是使用 EF 或任何其他 ORM,如果您只是不专注于混淆的强类型“DataRow”要求我有点这是大学的要求,我猜测使用 DataRow 是您希望实现的目标,因为您对过去编写的代码很熟悉。

请记住,MySQL、SQL Server、Oracle 数据库可以设计为“强类型”,并且实际上不能以任何其他方式轻松设计,因为列具有以下类型:varchar、int、decimal、 money、byte、guid、nvarchar等

您可以将每个数据库中的每一列都设为 blob 或字节,然后争辩说数据库是动态类型的,但这有点愚蠢。

C# 是一种“强类型”语言。

综上所述,只要大学没有明确要求您使用 DataRow 或 DataSet 来强制执行强类型,那么该解决方案可能符合要求,因为它仍然使用 ADO.NET:

public class AddressModel {
    public string Address1 { get; set; } //this is a strongly typed property
    public int Zip { get; set; } //this is a strongly typed property
}

public List<AddressModel> GetAddress(int addressId) {
    List<AddressModel> addressList = new List<AddressModel>();
    cmd.CommandText = @"SELECT Address1, Zip FROM [dbo].[Address]";
    using (SqlDataReader data = cmd.ExecuteReader())
    {
        while (data.Read())
        {
            AddressModel temp = new AddressModel();
            temp.Address1 = Sql.Read<String>(data, "Address1");
            temp.Zip = Sql.Read<Int32>(data, "Zip");
        }
    }

    return addressList;
}

public static class Sql
{
    public static T Read<T>(DbDataReader DataReader, string FieldName)
    {
        int FieldIndex;
        try { FieldIndex = DataReader.GetOrdinal(FieldName); }
        catch { return default(T); }

        if (DataReader.IsDBNull(FieldIndex))
        {
            return default(T);
        }
        else
        {
            object readData = DataReader.GetValue(FieldIndex);
            if (readData is T)
            {
                return (T)readData;
            }
            else
            {
                try
                {
                    return (T)Convert.ChangeType(readData, typeof(T));
                }
                catch (InvalidCastException)
                {
                    return default(T);
                }
            }
        }
    }
}

感谢this answer 提供了很好的Read 扩展方法,该方法将抛出无效类型转换异常

【讨论】:

  • @HenkHolterman 坚持使用强类型 DataRow 解决方案意味着什么?使用强类型 DataRow 的目的是什么,这难道不是一种相当过时的实现方式吗?
  • 是的,它已被弃用,但 OP 解决了所有这些问题。这是一种解决方法,但这不是所要求的。
  • @HenkHolterman 您确实说过我的回答完全没有抓住问题的重点,因此您建议他们唯一相关的答案是指导 OP 以某种方式使用已弃用,甚至可能是严厉的解决方案ADO.NET 设计模式/概念?
  • @HenkHolterman 你记下我的答案,这个答案试图帮助指导 OP 以 2017 年的方式而不是大约 1999 年的方式思考和查看解决方案,你绝不是正确的你的判断
【解决方案2】:

强类型数据集只是 Visual Studio 设计器使用 ADO.net 数据集生成的 c# 类。因此,如果支持 ADO.net(确实如此,请参见下面的链接),您应该能够使用现有的强类型数据集。请注意,我还没有尝试过,但这是我应该针对我现有的代码库研究的主题。

https://blogs.msdn.microsoft.com/devfish/2017/05/15/exploring-datatable-and-sqldbadapter-in-asp-net-core-2-0/

【讨论】:

    猜你喜欢
    • 2021-04-06
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2012-08-08
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多