.NET Core 2.0 强类型数据行

.NET Core 2.0 Strongly Typed DataRows

有没有办法在不使用 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 上做这样的事情。

即使strongly typed DataSets, DataRows etc. were available using a .NET Core Stack and ADO.NET which they are not, I think you will find in the .NET Core community today that there would be very little use of DataRow or DataSet at all and certainly not as a means to enforce strong typing, for example。 ADO.NET 为其一些关键对象(如 DataTable、DataRow、Dataset)提供开箱即用的 "strongly typed" 概念是一种老派的心态。如果你在这个时代想要一个强类型的解决方案,你只需定义你的类型并在尝试不正确的类型转换时抛出异常,或者甚至不抛出异常,C# 将为你抛出无效的转换异常。

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

我相信下面的代码是 "strongly typed" 解决方案,使用 .NET Core 2.0,ADO.NET 并且不使用 EF 或任何其他 ORM,如果您不关注强类型 "DataRow" 让我有点困惑的要求是大学的要求,我猜想使用 DataRow 是您希望实现的目标,因为您对过去编写的代码很熟悉。

请记住,MySQL、SQL 服务器、Oracle 数据库可以设计 "strongly typed",但实际上无法以任何其他方式轻松设计,因为列的类型如下:varcharintdecimalmoneybyteguidnvarchar

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

C# 是一种 "strongly typed" 语言。

综上所述,只要大学没有特别要求您使用 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 answerRead 扩展方法,该方法将抛出无效类型转换异常

Strongly-typed 数据集只是 visual studio 设计人员使用 ADO.net 数据集生成的 c# 类。因此,如果支持 ADO.net(支持,请参阅下面的 link),您应该能够使用现有的强类型数据集。请注意,我还没有尝试过,但这是我应该研究现有代码库的主题。

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