我承认,我在这方面的问题很大程度上是因为对解决方案中涉及的几个组件缺乏理解。我并不完全是实体框架的“新手”,代码优先,也不是泛型类型,但这三种类型的内部工作方式对我来说仍然很神秘,这让我觉得很适合。
我有一个代码优先项目,在该项目中,我将“模型”类与“服务”类分离开来,并在这两种类中都进行了泛化。我是而不是,使用完整的存储库模式,原因有很多。对我所做的大部分工作来说,我所拥有的结构是非常完美的--我理解它,而且它看起来相当干净。
但是有一个方面我遇到了问题,那就是能够将我的模型类类型之一作为泛型参数传递给泛型服务对象的实例,给出模型类的字符串路径/名称。
(背景:我需要这样做,因为我在数据库中用JSON文件的初始化值“种子”了几个表。这个JSON文件包含模型实体的名称。因此,在运行时,我需要获取该字符串值,然后将其作为类型提供给执行数据库操作的泛型服务对象。)
下面是相关的代码片段:
在BaseEntity.cs中,我具有顶级接口和许多抽象类,然后特定的模型实体继承这些类:
namespace POST.API.Models
{
public interface IEntity
{
int Id { get; set; }
}
public abstract class BaseEntity { }
public abstract class Entity : BaseEntity, IEntity
{
public virtual int Id { get; set; }
}
public abstract class TypeEntity : Entity
{
public TypeDefinition Definition { get; set; }
}
}在BaseService.cs中,我有另一个接口和更抽象的类,特定的模型服务类可以从中继承。这里还有一个用于执行insert操作的具体类:
namespace POST.API.Services
{
public interface IEntityService { }
public abstract class BaseEntityService<T> : IEntityService
where T : Models.BaseEntity
{
public T Fetch(int Id)
{
using (var Db = new PostDbContext())
{
return Db.Set<T>().Find(Id);
}
}
public void Create(T Item)
{
if (Item != null)
{
using (var Db = new PostDbContext())
{
DbSet Entity = Db.Set<T>();
Entity.Add(Item);
Db.SaveChanges();
}
}
}
public IEnumerable<T> All()
{
using (var Db = new PostDbContext())
{
return (IEnumerable<T>)Db.Set<T>().ToList();
}
}
}
public abstract class BaseTypeEntityService<T> : BaseEntityService<T>
where T : Models.TypeEntity
{ }
public abstract class BasePropertyTypeEntityService<T> : BaseTypeEntityService<T>
where T : Models.PropertyTypeEntity { }
public abstract class BasePropertyEntityService<T> : BaseEntityService<T>
where T : Models.BaseEntity { }
public class TypeEntityService<T> : BaseTypeEntityService<T>
where T : Models.TypeEntity { }
#endregion
}我删除了一些与演示无关的方法。
我有一些代码,然后尝试使用这些基类遍历JSON文件并插入一些行,因此:
using (PostDbContext Db = new PostDbContext())
{
string JsonString = System.IO.File.ReadAllText(JsonDataFile);
DataSet JsonDataSet = JsonConvert.DeserializeObject<DataSet>(JsonString);
foreach (DataTable Table in JsonDataSet.Tables)
{
Type EType = Type.GetType("POST.API.Models." + Table.TableName);
POST.API.Models.BaseEntity E = (POST.API.Models.BaseEntity)Activator.CreateInstance(EType);
Services.TypeEntityService<EType> S = new Services.TypeEntityService<EType>();
foreach (DataRow Row in Table.Rows)
{
// Set properties of E and call Create method of S
}
}
}我显然误解了一些基本的东西,因为这段代码不会编译。在这一行代码中:
Services.TypeEntityService<EType> S = new Services.TypeEntityService<EType>();...I在我对EType的引用上得到一个错误,编译器抱怨“无法找到类型或名称空间‘EType’”。
因此,很明显,那里的引用不能在运行时进行计算。这让我想知道我到底是怎么做到的。所有相关的话题似乎都无法给出令人满意的答案--至少在我自己的实施过程中,这样做是不合理的。
发布于 2017-02-22 17:07:45
您需要使用Activator创建Services.TypeEntityService<EType>,如下所示.
Type EType = Type.GetType("POST.API.Models." + Table.TableName);
Type[] typeArgs = { EType };
var generic = typeof(Services.TypeEntityService<>).MakeGenericType(typeArgs);
var S = Activator.CreateInstance(generic);https://stackoverflow.com/questions/42397625
复制相似问题