即使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 扩展方法,该方法将抛出无效类型转换异常