使用泛型方法的反射强制转换泛型实体

本文关键字:转换 泛型 实体 反射 泛型方法 | 更新日期: 2023-09-27 18:08:24

我有一个叫做RevertChanges的方法,它看起来像这样:

public static void RevertChanges<TEntity>()
{
            var jsonData = DataAccess.GetEnvironmentJson((int)Environments.Production);
            var model = JsonConvert.DeserializeObject<Models.FullDataSetModel>(jsonData);
            var targetEntity = typeof(TEntity).Name;
            using (var db = new LoginPageContentEntities())
            {
                db.Database.ExecuteSqlCommand(String.Format("TRUNCATE TABLE [{0}]", targetEntity));
                var modelValue = model.GetType().GetProperty(targetEntity).GetValue(model, null);
                var table = (DbSet)(typeof(LoginPageContentEntities).GetProperty(targetEntity).GetValue(db, null));
                table.AddRange((DbSet)modelValue);                         
                db.SaveChanges();
            }
}

我知道无论TEntity是什么都将匹配modelValue数据集。DbSet casting不起作用,我正在努力寻找如何返回具有泛型的整个实体。我发现,如果我使用(IEnumerable<TEntity>),我可以在表上调用ToList(),但是这不起作用,因为我需要能够调用添加范围。是否可以:

    返回具有泛型的实体引用?
  1. 访问AddRange,然后保存上下文?

对于上下文,我试图替换这个方法:

public static void RevertChanges(Environments targetToRestoreFrom, ContentFields tableToRevert)
        {
            var jsonData = DataAccess.GetEnvironmentJson((int)targetToRestoreFrom);
            var model = JsonConvert.DeserializeObject<Models.FullDataSetModel>(jsonData);            
            using (var db = new LoginPageContentEntities())
            {
                switch (tableToRevert)
                {
                    case ContentFields.ProductInformation:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [ProductInformation]");
                        db.ProductInformation.AddRange(model.ProductInformation);
                        break;
                    case ContentFields.DidYouKnow:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [DidYouKnow]");
                        db.DidYouKnow.AddRange(model.DidYouKnow);
                        break;
                    case ContentFields.MaintenanceMessage:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [MaintenanceMessage]");
                        db.MaintenanceMessage.AddRange(model.MaintenanceMessage);
                        break;
                    case ContentFields.TrainingEvent:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [TrainingEvents]");
                        db.TrainingEvents.AddRange(model.TrainingEvents);
                        break;
                    case ContentFields.VideoContent:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [HtmlSnippets]");
                        db.HtmlSnippets.AddRange(model.HtmlSnippets);
                        break;
                    case ContentFields.ProductMarketingUrl:
                        db.Database.ExecuteSqlCommand("TRUNCATE TABLE [ProductMarketingUrl]");
                        db.ProductMarketingUrl.AddRange(model.ProductMarketingUrl);
                        break;
                }                
                db.SaveChanges();
            }
        }

模型:

namespace LoginPageContentManager.Models
{
    public class FullDataSetModel
    {
        public List<DidYouKnow> DidYouKnow                   { get; set; }
        public List<HtmlSnippets> HtmlSnippets               { get; set; }
        public List<MaintenanceMessage> MaintenanceMessage   { get; set; }
        public List<ProductInformation> ProductInformation   { get; set; }
        public List<TrainingEvents> TrainingEvents           { get; set; }
        public List<ProductMarketingUrl> ProductMarketingUrl { get; set; }
    }
}

使用泛型方法的反射强制转换泛型实体

Set<T>方法允许您获得一般的DbSet

在您的示例中,您应该能够通过以下操作向集合添加:

db.Set<TEntity>().AddRange(modelValue)

您需要在DbContext上使用Set(Type entityType)方法。

类似这样的内容(未编译或测试):

var setType = typeof(MyModel).GetProperty(targetEntity).GetType();
db.Set(setType).AddRange(modelValue)