gpt4 book ai didi

c# - 需要调用 InsertBulk(IEnumerable pocos) 但 T 仅在运行时知道

转载 作者:行者123 更新时间:2023-12-02 17:40:55 24 4
gpt4 key购买 nike

NPoco(一种 .NET 微型 ORM,源自 PetaPoco)有一种在给定通用类型列表的情况下将记录批量插入数据库的方法。方法签名是:

void InsertBulk<T>(IEnumerable<T> pocos);

在内部,它采用类型 T 的名称,并使用它来确定要插入的数据库表(类似地,类型的属性名称映射到列名称)。 因此,将正确类型的变量传递给方法至关重要

我的挑战是:

  • 我得到了要插入数据库的对象列表,如 List<IDataItem>其中 IDataItem 是所有可插入对象的类都必须实现的接口(interface)
  • 列表可以包含实现 IDataItem 的任何类型的对象,并且列表中可能存在混合类型
  • 强调这个问题 - 我在编译时不知道必须传递给 InsertBulk 的实际具体类型

我尝试了以下方法,但是Convert.ChangeType的结果是Object,所以我将一个Object列表传递给InsertBulk,这是无效的。

   private static Exception SaveDataItemsToDatabase(List<IDataItem> dtos)
{
using (var db = new DbConnection())
{
try
{
var dtosByType = dtos.GroupBy(x => x.GetType());

db.Data.BeginTransaction();

foreach (var dataType in dtosByType)
{
var type = dataType.Key;
var dtosOfType = dataType.Select(x => Convert.ChangeType(x, type));

db.Data.InsertBulk(dtosOfType);
}

db.Data.CommitTransaction();

return null;
}
catch (Exception ex)
{
db.Data.RollbackTransaction();

return ex;
}
}
}

有什么办法可以实现这个目标吗?

最佳答案

您必须创建一个类型为 List<T> 的新列表并将所有项目复制到其中,然后调用 InsertBulk通过反射。

foreach(var g in groups)
{

var dataItemType = g.Key;
var listType = typeof(List<>).MakeGenericType(new [] { dataItemType });
var list = (IList) Activator.CreateInstance(listType);

foreach(var data in g)
list.Add(data);

db.Data.GetType()
.GetMethod("InsertBulk")
.MakeGenericMethod(dataItemType)
.Invoke(db.Data, new object[] { list });

}

在这里查看它的工作情况:https://dotnetfiddle.net/BS2FLy

关于c# - 需要调用 InsertBulk<T>(IEnumerable<T> pocos) 但 T 仅在运行时知道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36454620/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com