Entity Framework с хранимой процедурой «Get», которая возвращает сущности - PullRequest
0 голосов
/ 04 мая 2010

Я пытаюсь выполнить хранимую процедуру, которая возвращает данные с точно такими же столбцами, что и у объекта таблицы, который есть в моем проекте. Я установил свойство «Возвращает коллекцию» в диалоговом окне «Добавление функции импорта» для моего типа объекта.

Я получаю ошибку NullReferenceException при выполнении хранимой процедуры, и при дальнейшем копании кажется, что это происходит из-за отсутствия свойства EntityKey. Могу ли я что-то сказать, чтобы игнорировать эти особые свойства сущности?

У меня уже есть частичный класс для этой сущности с '[ScaffoldColumn (false)]', но это не имеет значения.

Ура, Ник

EDIT:

Вот трассировка стека:

[NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.] System.Data.EntityKey.AddHashValue (Int32 hashCode, Object keyValue) +36 System.Data.EntityKey.GetHashCode () +7696654 System.Collections.Generic.GenericEqualityComparer 1.GetHashCode(T obj) +23 System.Collections.Generic.Dictionary 2.FindEntry (клавиша TKey) +70 System.Collections.Generic.Dictionary 2.TryGetValue(TKey key, TValue& value) +17 System.Data.Objects.ObjectStateManager.TryGetEntityEntry(EntityKey key, EntityEntry& entry) +111 System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly(Func 2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet) +102 lambda_method (Closure, Shaper) +460 System.Data.Common.Internal.Materialization.Coordinator 1.ReadNextElement(Shaper shaper) +170 System.Data.Common.Internal.Materialization.SimpleEnumerator.MoveNext() +84 System.Collections.Generic.List 1..ctor (IEnumerable 1 collection) +406 System.Linq.Enumerable.ToList(IEnumerable 1 source) +58 TWAgencySpend.Controllers.ReportsController.Advertising (Nullable 1 agencyId, Nullable 1 businessUnitId) в C: \ dasdsd \ Controllers \ ReportsController.cs: 72 lambda_method (Closure, ControllerBase, Object []) +190 System.Web.Mvc.ActionMethodDispatcher.Execute (контроллер ControllerBase, параметры Object []) +51 System.Web.Mvc.ReflectedActionDescriptor.Execute (ControllerContext controllerContext, IDictionary 2 parameters) +409 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2 параметра) +52 System.Web.Mvc. <> C__DisplayClassd.b__a () +127 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (фильтр IActionFilter, предварительный контекст ActionExecutingContext, фильтры Func 1 continuation) +436 System.Web.Mvc.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() +61 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList 1, дескриптор ActionDescriptor, IDictionary 2 parameters) +305 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830 System.Web.Mvc.Controller.ExecuteCore() +136 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +111 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39 System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +65 System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +44 System.Web.Mvc.Async.<>c__DisplayClass8 1.b__7 (IAsyncResult _) +42 System.Web.Mvc.Async.WrappedAsyncResult`1.End () +141 System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, тег объекта) +54 System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, тег объекта) +40 System.Web.Mvc.MvcHandler.EndProcessRequest (IAsyncResult asyncResult) +52 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest (результат IAsyncResult) +38 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +8836913 System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое и завершено синхронно) + 184

Обновлено: вот элемент в SSDL для функции:

    <Function Name="GetAgencyReport" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
      <Parameter Name="AgencyId" Type="int" Mode="In" />
      <Parameter Name="Year" Type="int" Mode="In" />
    </Function>

и вот звонок:

reportsViewModel.AgencyReportData = twAgencySpendEntities.GetAgencyReport(agencyId.Value, 2010).ToList();

и вот ключ для моей сущности:

<EntityType Name="AdvertisingData">
  <Key>
    <PropertyRef Name="AgencyId" />
    <PropertyRef Name="BusinessUnitId" />
    <PropertyRef Name="Month" />
    <PropertyRef Name="Year" />
  </Key>
  <Property Name="AgencyId" Type="int" Nullable="false" />
  <Property Name="BusinessUnitId" Type="int" Nullable="false" />
  <Property Name="Month" Type="int" Nullable="false" />
  <Property Name="Year" Type="int" Nullable="false" />
  ...

1 Ответ

3 голосов
/ 06 мая 2010

Во-первых, причина, по которой платформа пытается разыменовать EntityKey, заключается в том, что свойство MergeOption для вашего запроса установлено в AppendOnly. Там нет ничего удивительного, так как AppendOnly по умолчанию. С AppendOnly платформа проверит каждую сущность, загруженную в память, и попытается исправить ссылки так, чтобы:

  1. Один и тот же объект никогда не может быть загружен в память дважды в двух разных местах, даже если вы дважды запросите его из базы данных.
  2. Любая сущность, которая ссылается на эту сущность, всегда будет указывать на одну и ту же ссылку.

Объекты идентифицируются с помощью свойства EntityKey, которое учитывает ссылку на это свойство в публикуемом вами стеке вызовов.

Таким образом, одним из вариантов будет изменение MergeOption в выполняемом запросе на NoTracking. Часто это лучший выбор для запроса только для чтения. Просто имейте в виду, что возвращаемые объекты нельзя использовать в качестве ссылочных объектов при редактировании других объектов.

Другой вариант - выяснить, почему EntityKey равен нулю. Я до сих пор не вижу полный EDMX для вашего процесса, но ключ в вашем CSDL достаточно сложен, так что я предполагаю, что он просто не соответствует сущности совершенно правильно, поэтому EF не может понять, как создать правильный EntityKey пока он материализует сущности из вашего процесса.

...