带有'Get'存储过程的实体框架,返回实体

时间:2010-05-04 12:24:53

标签: stored-procedures entity-framework-4

我正在尝试执行一个存储过程,该存储过程返回的数据与我在项目中的表实体的列完全相同。我在“添加函数导入”对话框中将“返回集合”属性设置为我的实体类型。

执行存储过程时出现NullReferenceException错误,并且进一步挖掘它似乎是因为缺少'EntityKey'属性。有什么我可以告诉它忽略实体的那些特殊属性吗?

我已经使用'[ScaffoldColumn(false)]'为该实体设置了一个部分类,但这似乎并不重要。

干杯, 尼克

编辑:

这是堆栈跟踪:

  

[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 key)+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 controller,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。&lt;&gt; c__DisplayClassd.b__a()+127      System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter过滤器,ActionExecutingContext preContext,Func 1 continuation) +436 System.Web.Mvc.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() +61 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList 1个过滤器,ActionDescriptor 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,Object tag)+54      System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+40      System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)+52      System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)+38      System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+8836913      System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+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 个答案:

答案 0 :(得分:3)

首先,框架尝试取消引用EntityKey的原因是您的查询的MergeOption属性设置为AppendOnly。没有什么大惊喜,因为AppendOnly是默认值。使用AppendOnly,框架将检查加载到内存中的每个实体并尝试修复引用,以便:

  1. 同一个实体永远不能在两个不同的位置加载到内存中两次,即使您从数据库中查询两次也是如此。
  2. 任何引用该实体的实体将始终指向同一参考。
  3. 通过EntityKey属性识别实体,该属性说明您发布的调用堆栈中对此属性的引用。

    因此,一种选择是将您正在运行的查询的MergeOption更改为NoTracking。这通常是只读查询的最佳选择。请注意,在编辑其他实体时,返回的实体不能用作引用的实体。

    另一种选择是找出EntityKey为空的原因。我仍然没有看到你的proc的完整EDMX,但是你的CSDL中的密钥非常复杂,我认为它不会很好地映射到实体,所以EF无法弄清楚如何构造正确的{{ 1}}虽然它是从你的proc中实现实体。