2015-03-06 2 views
0

У меня есть настройка EF6 для SQL-сервера db с примерно 60 таблицами. У меня есть сущности для каждой таблицы. То, что я пытаюсь сделать, это запустить тот же метод против множества этих объектов, которые будут известны во время выполнения. Этот метод представляет собой процедуру qa/qc, которая проверяет некоторые данные для определенных полей, которые гарантированы в каждой таблице. Я предполагаю, что я хочу сделать, чтобы сущность была параметром метода, поэтому я могу называть ее последовательным образом. Я также хотел бы сделать набор объектов для передачи в качестве параметра. примерно следующее:Использование наборов сущностей Entity Framework во время выполнения

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

Это можно сделать? Это работа для размышлений?

EDIT

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 раз. Я думаю, что я ищу способ «кормить» набор объектов для этого единственного метода. Кроме того, большое спасибо за помощь. Я многому учусь.

ответ

2

Вы должны абстрагироваться интерфейс (Entity Framework не будет даже уведомление):

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-Per-Type/Table-Per-Hierarchy, поэтому я начну с этого, а затем рассмотрю возможность внедрения либо abstract, либо конкретного базового класса в качестве улучшения.

EDIT

Может быть, ваш ищет что-то проще, чем я думал, что первый, на основе последнего комментария.

Давайте дадим себя то, что 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. Например.

// 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); } 
    } 
} 
+0

Наконец-то у вас была возможность посмотреть это. Спасибо за предложение. это действительно здорово. несколько вопросов - 1) Я изменяю сгенерированный EF-код и не уничтожусь, если я регенерирую свою модель ef из базы данных? 2), чтобы расширить ваш пример кода, когда я вхожу в MyQaQcMethod, и я ссылаюсь на «сущность», я получаю доступ к свойству CommonInt, которое является приятным. Но мне действительно нужен доступ к самой сущности, поэтому я могу написать запрос лямбда. – VBAHole

+0

Я изо всех сил пытаюсь сообщить, что я пытаюсь сделать. Я пытаюсь проверить поля в этих объектах. поэтому мой метод qaqc похож на var q = db.ROUTES.Where (o => o.Route_ID == null); Это работает отлично, если я нацелен на одну сущность. Но теперь я хочу запустить ту же проверку на 60 объектах – VBAHole

+0

в коде, который вы предложили, когда я получаю вызов MyQaQcMethod (e) e - фактически объект с параметрами по умолчанию. то, что я ищу, является эквивалентом db.EntityA, чтобы я мог тогда делать. Где против. Я действительно не хочу, чтобы фактическая сущность я хочу концепцию сущности, которую я хочу заполнить с помощью запроса. очевидно, я не получу семантику правильно. Извини за это. – VBAHole

Смежные вопросы