Entity Framework 4.1 - динамическая загрузка - PullRequest
2 голосов
/ 21 декабря 2011

У меня есть модель Entity Framework (некоторые свойства были исключены для простоты):

public class Media
{
    public int MediaID { get; set; }
    public ICollection<Track> Tracks { get; set; }
    public ICollection<RelatedMedia> RelatedMedias { get; set; }
}

У меня тогда есть мой DbContext:

public class MediaServiceContext : DbContext
{
    public DbSet<Media> Medias { get; set; }
}

Затем я могу получить данные, используя следующее, и это прекрасно работает:

public Media Media_Get(int id)
    {
        using (MediaServiceContext mc = new MediaServiceContext())
        {
            return mc.Medias.Include("Tracks").Include("RelatedMedias").Single(m => m.MediaID == id);
        }
    }

Мой вопрос заключается в том, что в некоторых случаях я не хочу загружать один или оба связанных объекта в зависимости от того, какая часть моего приложения вызывает этот код; Как я могу сделать динамический Включает?

Я пробовал это:

public Media Media_Get(int id, bool includeRelated, bool includeTracks)
    {                  
        using (MediaServiceContext mc = new MediaServiceContext())
        {
            IQueryable<Media> query = mc.Medias;

            if (includeRelated)
                query = query.Include("RelatedMedias");

            if (includeTracks)
                query = query.Include("Tracks");

            return query.Single(m => m.MediaID == id);
        }
    }

... но я получаю исключение "Указанный приведен в неверном".

Я также пытался это предложенное решение, но оно выдает ', неспособное привести DbQuery к ObjectQuery' исключение. Изменение метода расширения в связанном решении с источника '(ObjectQuery)' на '(DbQuery) source' вызывает то же самое 'Указанное приведение недопустимо' исключение.

Я охотился высоко и низко за решением этой проблемы, но безуспешно. Любая помощь будет высоко ценится.

Поправка - Вот трассировка стека:

   at System.Data.SqlClient.SqlBuffer.get_Int64()
   at lambda_method(Closure , Shaper )
   at System.Data.Common.Internal.Materialization.Coordinator.HasNextElement(Shaper shaper)
   at System.Data.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MoveNext()
   at System.Data.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.TryReadToNextElement()
   at System.Data.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at API.Areas.V1.Models.RetailerManager.Media_Get(Int32 id, String retailerKey, Boolean includeLicenses, Boolean includeProperties, Boolean includeRelated, Boolean includeTracks) in C:\Users\garth\Documents\Development\WebApplications\api\Areas\V1\Models\RetailerManager.cs:line 28
   at API.Areas.V1.Controllers.RetailerController.Media(Nullable`1 id, String httpVerb, Boolean includeLicenses, Boolean includeProperties, Boolean includeRelated, Boolean includeTracks) in C:\Users\garth\Documents\Development\WebApplications\api\Areas\V1\Controllers\RetailerController.cs:line 25
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)

1 Ответ

1 голос
/ 22 декабря 2011

Ваша трассировка стека показывает, что .SingleOrDefault() вызвало это исключение, но я не вижу .SingleOrDefault() в вашем коде.

Я вижу это:

return query.Single(m => m.MediaID == id);

Возможно ли, что Media.MediaID является long, а не int?

Обновление

В качестве другой альтернативы для ответа на ваш первоначальный вопрос, я ответил на вопрос пару недель назад относительно этого . Пример кода в моем ответе связан с динамическим упорядочением по, но мы используем очень похожий шаблон для динамической активной загрузки (см. Первый комментарий после моего ответа).

Вместо подписи метода, подобной этой:

public Media Media_Get(int id, bool includeRelated, bool includeTracks)

Ваша подпись будет выглядеть примерно так:

public Media Media_Get(MediaGetter mediaGetter)

... и вы бы использовали это так:

var media = someInstance.Media_Get(
    new MediaGetter { ID = id, }
        .EagerLoad(m => m.Tracks)
        .EagerLoad(m => m.RelatedTracks)
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...