在运行时使用实体框架实体集

时间:2015-03-06 06:13:28

标签: entity-framework

我对一个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;这个单一方法的一组实体。 另外,非常感谢你帮助我。我经常学习。

1 个答案:

答案 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);
}

现在,您可以提取一个基类,每个基类派生实际为每个需要它们的实体实现CommonIntCommonString属性,但是每种类型的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); }
    }
}