我对一个sql server db进行了EF6设置,其中包含大约60个表。 我有每个表的实体。我试图做的是对运行时已知的一组这些实体运行相同的方法。 该方法是一个qa / qc例程,它对确保在每个表中的特定字段进行一些数据检查。 我想我想做的是让实体成为方法的参数,这样我就可以连续调用它。 我还想让一组实体作为参数传递。 像这样的东西:
List<string> entList = new List<string>(){"Table1","Table2","Table3"};
foreach (entName in entList)
{
//create an entity with the string name
//call myQAQCMethod with the entity
}
MyQAQCMethod (entity SomeEntity)
{
//run against this entity
doQAQC(SomeEntity);
}
可以这样做吗?这是反思的工作吗?
修改
using (var context = new Context())
{
var results = context.EntityAs.Where(a => a.Prop1 == e.Prop1)
.Where(a => a.Prop2 == e.Prop2)
.Select(a => new
{
APropertyICareAbout = a.Prop1,
AnotherPropertyICareAbout = a.Prop2
}).ToArray();
}
正是我想要的。问题是我想避免键入这个循环60次。我想我正在寻找一种方式来喂养&#34;这个单一方法的一组实体。 另外,非常感谢你帮助我。我经常学习。
答案 0 :(得分:2)
您需要抽象一个界面(实体框架甚至不会注意到):
interface IQaQcable
{
int CommonInt { get; set; }
string CommonString { get; set; }
}
public class EntityA : IQaQcable
{
public int Id { get; set; }
public int CommonInt { get; set; }
public string CommonString { get; set; }
// other properties and relations
}
public class EntityB : IQaQcable
{
public int Id { get; set; }
public int CommonInt { get; set; }
public string CommonString { get; set; }
// other properties and relations
}
// in some unknown utility class
void MyQaQcMethod<T>(T entity) where T : IQaQcable
{
doSomethingWithIQaQcableProperties(entity.CommonInt, entity.CommonString);
}
// in some unknown test class
void Test()
{
var entities = new List<IQaQcable> { new EntityA(), new EntityB() };
foreach (var e in entities)
MyQaQcMethod(e);
}
现在,您可以提取一个基类,每个基类派生实际为每个需要它们的实体实现CommonInt
和CommonString
属性,但是每种类型的Table可能会变得棘手/ Table-Per-Hierarchy,所以我从这开始,然后考虑引入abstract
或具体的基类作为改进。
修改强>
根据您的上一条评论,也许您正在寻找比我最初想象的更简单的东西。
让我们自己给出DbContext
这样的内容:
class Context : DbContext
{
public virtual DbSet<EntityA> EntityAs { get; set; }
public virtual DbSet<EntityB> EntityBs { get; set; }
}
所以,可能只是你希望这样做:
using (var context = new Context())
{
var results = context.EntityAs.Where(a => a.Prop1 == e.Prop1)
.Where(a => a.Prop2 == e.Prop2)
.Select(a => new
{
APropertyICareAbout = a.Prop1,
AnotherPropertyICareAbout = a.Prop2
}).ToArray();
}
请记住,如果实体类中有一些共同的属性,您仍然可以执行以下操作:
IEnumerable<T> MyQaQcMethod(IQueryable<T> entities, T referenceEntity) where T : IQaQcAble
{
return entities.Where(e => SomePredicate(e, referenceEntity));
}
void Test()
{
using (var context = new Context())
{
// EntityA implements IQaQcAble
var resultsForA = MyQaQcMethod(context.EntityAs, defaultEntity).ToArray();
// so does EntityB, so can call with either
var resultsForB = MyQaQcMethod(context.EntityBs, defaultEntity).ToArray();
}
}
请记住,为避免修改生成的实体类,您可以使用interface
类在单独的源文件中实现interface
成员和partial
。 E.g。
// IQaQcAble.cs
internal interface IQaQcAble
{
int CommonInt { get; set; }
string CommonString { get; set; }
}
// a class whose existing property names match the interface
public partial class EntityA : IQaQcAble
{
int IQaQcAble.CommonInt
{
get { return CommonInt; }
set { CommonInt = value; }
}
string IQaQcAble.CommonString
{
get { return CommonString; }
set { CommonString = value; }
}
}
// a class whose property names differ
public partial class EntityB : IQaQcAble
{
int IQaQcAble.CommonInt
{
get { return SomeOtherInt; }
set { SomeOtherInt = value; }
}
string IQaQcAble.CommonString
{
get { return SomeOtherInt.ToString(); }
set { SomeOtherInt = Convert.ToInt32(value); }
}
}