我正在使用codeDOM在运行时生成我的实体类。我还有一个通用的存储库来处理各种数据库功能。这是作为我的通用存储库中的示例方法的Insert方法:
public void Insert<TEntity>(TEntity entity) where TEntity : class, IBusinessEntity
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
TEntity existing = Existing(entity);
if (existing == null)
{
_context.Set<TEntity>().Add(entity);
this._context.SaveChanges();
}
}
以下是我如何生成实体类以及如何使用codeDOM基于该实体类创建实体的示例代码:
//Generate the fields of the new entity class
EntityGenerator.EntityFieldInfo entityField1 = new EntityGenerator.EntityFieldInfo("Name", typeof(string), RelationshipType.NoRelation);
EntityGenerator.EntityFieldInfo entityField2 = new EntityGenerator.EntityFieldInfo("Shape", typeof(string), RelationshipType.NoRelation);
ICollection<EntityGenerator.EntityFieldInfo> entityFieldList = new List<EntityGenerator.EntityFieldInfo> { entityField1, entityField2 };
// Create the new entity class using the fields established above
// as well as the name of the entity (typeName = "Thing")
string typeName = "Thing";
EntityGenerator.CreateEntityClass(entityFieldList, typeName);
CompilerResults results = EntityGenerator.GetCompiledEntity(typeName);
// Create an entity instance based on the new entity class that was just created
Object newThing = EntityGenerator.CreateInstanceOfEntity(results, typeName);
SetObjectField(newEntity, "Name", "Box");
SetObjectField(newEntity, "Shape", "Cuboid");
如您所见,newThing(新实体实例)是一种Object类型。如果这是一个硬编码的实体类,那么我可以说
Thing newThing;
但CodeDOM创建的Thing实体不是硬编码类,因此我必须使用Object类型而不是Thing类型。这是一个问题,因为我使用的是通用存储库。让我们说我想将这个实体插入数据库。我想打个电话:
myRepository.Insert<Thing>(newThing);
但是,Thing只是在运行时由CodeDOM创建的,所以它不是一个类,这意味着它不能进入&lt;&gt;。您可能已经在我的Insert方法中注意到,TEntity也是一个IBusinessEntity。如果我试试
myRepository.Insert<IBusinessEntity>(newThing);
我收到错误:
参数类型&#39;对象&#39;不能分配给参数类型&#39; Models.IBusinessEntity&#39;
如果我在&lt;&gt;中没有任何内容尝试,请执行以下操作:
myRepository.Insert(newThing);
我收到错误:
类型&#39;对象&#39;必须可转换为&#39; Models.IBusinessEntity&#39;为了将它用作参数&#39; TEntity&#39;在通用方法&#39; void Insert(TEntity)&#39;。
有谁知道如何协调这个codeDOM生成的实体与通用存储库?反思有帮助吗?如果反思可以某种方式给我一类可以传递给&lt;&gt;的东西,那将是很好的。另外我应该注意,我使用CodeDOM创建的所有实体都扩展了IBusinessEntity。
答案 0 :(得分:1)
我认为很难使它工作,因为DbContext中包含的DbSets被EF用来创建映射。你觉得如何创造它们?
无论如何,您不需要使用EF类型,您通常可以使用GetType。 在您的方法中(缺少现有(。)但我认为类似)您可以使用
public void Insert(object entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
if (!(entity is IBusinessEntity))
throw new ArgumentInvalidException("entity is not an IBusinessEntity");
object existing = Existing(entity);
if (existing == null)
{
_context.Set(entity.GetType()).Add(entity);
this._context.SaveChanges();
}
}
使用Set&lt;&gt;或Set(。)我很确定EF将搜索从DbContext中包含的DbSets开始创建的映射。我不记得确切的异常,但我播种的时间不同(当我使用DbContext.Set(myEntityType)时)。