2011-02-16 59 views
6

Pocos和可空的外鍵有問題。 我有2個表(訂單和產品)每個表都有一個複合主鍵(orderid,orderid2)和(productid,productid2) 我已經在兩個表之間設置了0,1 .. *關聯。 一個訂單可能與0或1個產品有關。 一個產品有*與他有關的命令。使用空的複合外鍵進行關聯修復時出現異常

如何崩潰:

  • 創建使用的CreateObject一個新產品()。
  • 將新產品添加到當前的實體集。
  • 創建一個新訂單usung CreateObject()。
  • 將新訂單添加到實體集。

當我添加訂單到產品的訂單列表中,它崩潰試圖修正內容協會(設置新秩序的產品導航性能)

CREATE TABLE [dbo].[Products](
    [productid] [int] IDENTITY(1,1) NOT NULL, 
    [productid2] [int] NOT NULL, 
    [productname] [nchar](10) NULL, 
CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED 
(
    [productid] ASC, 
    [productid2] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

CREATE TABLE [dbo].[Orders](
    [orderid] [int] NOT NULL, 
    [orderid2] [int] NOT NULL, 
    [ordername] [nchar](10) NULL, 
    [productid] [int] NULL, 
    [productid2] [int] NULL, 
CONSTRAINT [PK_orders] PRIMARY KEY CLUSTERED 
(
    [orderid] ASC, 
    [orderid2] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

Entity model

代碼崩潰:

  var product = context.CreateObject<Products>(); 
      context.Products.AddObject(product); 
      var order = context.CreateObject<Orders>(); 
      context.Orders.AddObject(order); 

      product.Orders.Add(order); 
      if (order.Product != product) Console.WriteLine("error"); 

例外:

System.Data.EntityException was unhandled 
    Message=Unable to set field/property Product on entity type System.Data.Entity.DynamicProxies.Orders_A0290D8629F0336D278E5AEF2C0F2A91FF56726ED5E3A9FA668AC902696A8651. See InnerException for details. 
    Source=System.Data.Entity 
    StackTrace: 
     at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.SetNavigationPropertyValue(RelatedEnd relatedEnd, Object value) 
     at System.Data.Objects.Internal.EntityWrapper`1.SetNavigationPropertyValue(RelatedEnd relatedEnd, Object value) 
     at System.Data.Objects.DataClasses.EntityReference`1.AddToObjectCache(IEntityWrapper wrappedEntity) 
     at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges) 
     at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity, Boolean applyConstraints) 
     at System.Data.Objects.DataClasses.EntityCollection`1.Add(TEntity entity) 
     at Proxies.CSharp.Program.Main(String[] args) in Program.cs:line 20 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: System.NullReferenceException 
     Message=Object reference not set to an instance of an object. 
     Source=Proxies.CSharp 
     StackTrace: 
      at Proxies.CSharp.Orders.FixupProduct(Products previousValue, Boolean skipKeys) in Orders.cs:line 134 
      at Proxies.CSharp.Orders.set_Product(Products value) in Orders.cs:line 106 
      at System.Data.Entity.DynamicProxies.Orders_A0290D8629F0336D278E5AEF2C0F2A91FF56726ED5E3A9FA668AC902696A8651.SetBasePropertyValue(String , Object) 
      at lambda_method(Closure , Object , String , Object) 
      at System.Data.Objects.Internal.EntityProxyFactory.TrySetBasePropertyValue(Type proxyType, String propertyName, Object entity, Object value) 
      at System.Data.Objects.Internal.EntityProxyFactory.<>c__DisplayClass8.<CreateBaseSetter>b__7(Object entity, Object value) 
      at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.SetNavigationPropertyValue(RelatedEnd relatedEnd, Object value) 

注:它的工作原理與entytobjects,其工作原理與自跟蹤實體,和它的工作原理,如果關鍵是不是複合或不能爲空。

我做錯了什麼或它是一個真正的錯誤?

回答

6

我不得不糾正POCO TT:

恰克行(381441和475):

<#=code.Escape(dependentProperty)#> = <#=code.Escape(navProperty)#>.<#=code.Escape(principalProperty)#>; 

由行:

<#=code.FieldName(dependentProperty)#> = <#=code.Escape(navProperty)#>.<#=code.Escape(principalProperty)#>; 
+0

我想說你最好在發電機的現場報告,然後檢查並看到你已經做到了。獎勵! – mcyalcin 2011-02-25 12:53:10

0

我假設您正在使用this poco實體生成器,或者執行一些類似的關係修復。如果是這樣,這是一個錯誤,你做錯了什麼(即有辦法做你想做的,而不會觸及上述錯誤)。

如果你使用:的

order.Product = product; 

代替

product.Orders.Add(order); 

它會做你想要什麼。

問題出在Order對象的FixupProducts方法(或者更確切地說是與productid setter的交互中)。 Fixup方法調用productid setter,setter將Product設置爲null,並且當Fixup方法繼續設置productid2時,它會嘗試使用該Product的空指針異常。

當然,您可以在其他情況下遇到類似的問題(儘管我現在無法想象)。如果你看看生成的類,我相信你可以找到一個合適的解決方案。關於我的頭頂,我會說在修正中跳過二傳手會解決這個問題,但我沒有想到它的含義或測試過,所以請自行承擔風險。

嘗試更換:

productid = Product.productid; 

productid2 = Product.productid2; 

_productid = Product.productid; 

_productid2 = Product.productid2; 
+0

感謝您的回覆。我知道這個解決方法,但它正在尋找一種可以同時工作的解決方案。 你的第二個建議似乎有效,我不知道爲什麼我沒有嘗試它;) 我所有的單元測試都是綠色的,所以我想這是一個很好的修正。 – oleveau 2011-02-25 08:24:14