Как правило, вернуть элемент из Entity Framework - PullRequest
2 голосов
/ 19 февраля 2011

У меня есть ситуация, когда веб-сайт может запрашивать данные из моей базы данных на основе строки (не волнуйтесь - я защищаю от SQL-инъекций). По разным причинам я хотел бы иметь единственный метод, который возвращает объект (из EF), который ожидает пользователь (который, в конечном счете, возвращается через частичную страницу).

Я думаю что-то вроде этого:

public <GenericType?> GetObject(int id, string typeName) {
  switch(typeName) {
    case "Type1":
      return db.Type1s.SingleOrDefault(t => t.TypeID == id);
    case "Type2":
      return db.Type2.SingleOrDefault(t => t.TypeID == id);
    default:
      return null;
  }
}

Можно ли сделать что-то подобное? (Чего я пытаюсь избежать, так это того, что нужно было выполнить оператор switch ранее, а затем вызвать определенный метод Repository, потому что тогда мне пришлось бы повторять код и делать это несколько раз.)

Ответы [ 4 ]

2 голосов
/ 19 февраля 2011

CreateQuery<T> может быть то, что вам нужно.

Имеет ли Entity Framework эквивалент DataContext.GetTable из Linq2Sql (ObjectContext.CreateQuery ?)

Есть ли какой-нибудь способ, которым вы можете получить все возможные типы, которые вы будете передавать, для совместимости с определенным интерфейсом, на котором есть это свойство TypeID? Если да, то как насчет:

    public T GetResult<T>(int id, string typeName) where T : IClassWithTypeID {
        YourEntities db = new YourEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeName));

        return result.Single(t => t.TypeID == id);
    }
1 голос
/ 19 февраля 2011

Как насчет

    public T GetResult<T>(int id, string typeName) {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeName));

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "TypeID"),
                Expression.Constant(id)),
            param);

        return result.Single(lambda);
    }

Полагаю, что связать дерево выражений вручную не так сложно, как я думал.

1 голос
/ 19 февраля 2011

С практической точки зрения любой обобщенный генератор отчетов / исполнитель запросов и т. Д., Вероятно, лучше подходит для прямых SQL-запросов, чем для встраивания вашей динамической логики в EF или LINQ.

0 голосов
/ 19 февраля 2011

Учитывая, как все будет выглядеть, когда вы вызываете этот метод ... предположительно, это будет выглядеть примерно так:

object obj = GetObject(257, "Type1");

Я не могу придумать, как сделать тип возвращаемого значения более конкретным, поскольку объекты в EF не имеют общего базового класса и не реализуют общий интерфейс. Конечно, вы могли бы заставить их реализовать такой интерфейс (как предполагает Адам, хотя и с другой целью), а затем переписать ваш метод следующим образом:

public IMyInterface GetObject(int id, string typeName) {
    switch(typeName) {
        case "Type1":
            return (IMyInterface)db.Type1s.SingleOrDefault(t => t.TypeID == id);
        case "Type2":
            return (IMyInterface)db.Type2.SingleOrDefault(t => t.TypeID == id);
        default:
            return null;
    }
}

Тогда ваш код вызова будет выглядеть так:

IMyInterface intf = GetObject(257, "Type1");
intf.DoSomethingHelpful();

Конечно, мое предположение о вашем телефонном коде может быть неверным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...