【发布时间】:2020-12-14 09:14:26
【问题描述】:
我有很多模型类,我用 API 中的数据填充它们。
API 数据的结构是 DataRow。
对于每个类,都有从 DataRow 到模型类的隐式转换。
我必须为每个模型类编写一组函数。其中一个函数,从数据库中获取,对于所有模型类都是通用的,所以我决定为此编写具有泛型类型的函数。
这是一个模型类的例子:
public class Person
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public static implicit operator Person(DataRow dataRow)
{
if (dataRow != null)
{
return new Person
{
Id = long.Parse((string)dataRow["Id"]),
FirstName = (string)dataRow["FirstName"],
LastName = (string)dataRow["LastName"]
};
};
return null;
}
}
具有用于强制转换的泛型类型的类示例,如下所示:
public class DefaultRepository<T>
{
public T CreateInstanceOfModelFromDataRow(DataRow dataRow)
{
T modelInstance = (T)Activator.CreateInstance(typeof(T));
modelInstance = (T)dataRow;
return modelInstance;
}
}
测试代码如下所示:
// for testing I will create DataTable and DataRow and populate it fake data
DataTable fakeTable = new DataTable();
fakeTable.Columns.Add("Id");
fakeTable.Columns.Add("FirstName");
fakeTable.Columns.Add("LastName");
DataRow fakeRow = fakeTable.NewRow();
fakeRow["Id"] = "1";
fakeRow["FirstName"] = "John";
fakeRow["LastName"] = "Doe";
// Cast DataRow to Pesron without error
Person fakePerson01 = (Person)fakeRow;
// Cant cast on this way create error while compiling
DefaultRepository<Person> defRepo = new DefaultRepository<Person>();
Person fakePerson02 = defRepo.CreateInstanceOfModelFromDataRow(fakeRow);
在 modelInstance = (T)dataRow; 行编译“无法将类型'System.Data.DataRow' 转换为'T'”时出现错误
我也尝试使用(T)Convert.ChangeType(dataRow, typeof(T));,但没有运气。
是否可以进行这种转换?
【问题讨论】:
-
您正在重建 EF Core 或 Dapper。为什么?除了必须处理 DataTable 的缺点之外,您一无所获。使用 Dapper,所有这些代码都将替换为
conn.Query<Person>("select * from Persons where LastName=@name.",new {name="Doe"});。 -
另一方面,如果你使用 EF Core,你甚至不需要存储库,你会得到一个开箱即用的工作单元和参数化SQL 生成。
-
感谢@PanagiotisKanavos 的建议,但我不能使用任何 ORM,因为没有直接访问数据库的权限。
-
感谢@WimOmbelets,但我无法使用该解决方案,因为来自 DataRow(s) 和模型类的字段名称冲突太多。如果我要使用这个解决方案,我需要为每个模型类创建映射,并且已经编写了转换。