Entity Framework CTP5 - чтение нескольких наборов записей из хранимой процедуры - PullRequest
11 голосов
/ 10 марта 2011

В EF4 это было нелегко. Вам пришлось либо перейти на классический ADO.NET (DataReader), либо использовать ObjectContext.Translate , либо использовать проект EFExtensions .

Было ли это реализовано в EF CTP5?

Если нет, каков рекомендуемый способ сделать это?

Нужно ли нам приводить DbContext<T> как IObjectContextAdapter и обращаться к базовому ObjectContext, чтобы перейти к этому методу?

Может кто-нибудь указать мне хорошую статью о том, как сделать это с EF CTP5?

1 Ответ

11 голосов
/ 16 марта 2011

Итак, у меня все получилось, вот что у меня есть:

internal SomeInternalPOCOWrapper FindXXX(string xxx)
{
    Condition.Requires(xxx).IsNotNullOrEmpty();

    var someInternalPokey = new SomeInternalPOCOWrapper();
    var ctx = (this as IObjectContextAdapter).ObjectContext;

    var con = new SqlConnection("xxxxx");
    {
        con.Open();
        DbCommand cmd = con.CreateCommand();
        cmd.CommandText = "exec dbo.usp_XXX @xxxx";
        cmd.Parameters.Add(new SqlParameter("xxxx", xxx));

        using (var rdr = cmd.ExecuteReader())
        {
            // -- RESULT SET #1
            someInternalPokey.Prop1 = ctx.Translate<InternalPoco1>(rdr);

            // -- RESULT SET #2
            rdr.NextResult();
            someInternalPokey.Prop2 = ctx.Translate<InternalPoco2>(rdr);

            // -- RESULT SET #3
            rdr.NextResult();
            someInternalPokey.Prop3 = ctx.Translate<InternalPoco3>(rdr);

            // RESULT SET #4
            rdr.NextResult();
            someInternalPokey.Prop4 = ctx.Translate<InternalPoco4>(rdr);
        }
        con.Close();
    }

    return someInternalPokey;
}

По сути, это в основном как классический ADO.NET. Вы читаете DbReader, переходите к следующему набору результатов и т. Д.

Но, по крайней мере, у нас есть метод Translate, который, по-видимому, делает слева направо между полями набора результатов и предоставленной сущностью.

Обратите внимание, что метод является внутренним.

Мой репозиторий вызывает этот метод, затем гидратирует DTO в мои доменные объекты.

Я не на 100% доволен этим по 3 причинам:

  1. Мы должны разыграть DbContext как IObjectContextAdapter. Метод Translate должен быть DbContext<T> класса IMO.
  2. Мы должны использовать классические объекты ADO.NET. Зачем? Хранимые процедуры должны иметь для любого ORM. Моя главная проблема с EF - отсутствие поддержки хранимых процедур, и это, похоже, не было исправлено с EF CTP5.
  3. Вы должны открыть новый SqlConnection. Почему он не может использовать то же соединение, что было открыто EF Context?

Надеюсь, это поможет кому-то и отправит сообщение команде EF. Нам нужна поддержка нескольких результатов для SPROCS с полки. Вы можете сопоставить хранимый процесс сложному типу, так почему мы не можем отобразить хранимый процесс на несколько сложных типов ?

...