Entity framework 使用可为空的复合外键进行关联修复期间出现异常

Entity framework 使用可为空的复合外键进行关联修复期间出现异常,entity-framework,poco,Entity Framework,Poco,我对Pocos和可空外键有问题。 我有两个表(订单和产品),每个表都有一个复合主键(orderid,orderid2)和(productid,productid2) 我在两个表之间设置了0,1..*关联。 一个订单可以与0或1个产品相关。 还有一种产品有与他相关的订单 如何崩溃: var product = context.CreateObject<Products>(); context.Products.AddObject(prod

我对Pocos和可空外键有问题。 我有两个表(订单和产品),每个表都有一个复合主键(orderid,orderid2)和(productid,productid2) 我在两个表之间设置了0,1..*关联。 一个订单可以与0或1个产品相关。 还有一种产品有与他相关的订单

如何崩溃:

            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");
  • 使用CreateObject()创建新产品
  • 将新产品添加到entityset
  • 使用CreateObject()创建新订单
  • 将新订单添加到entityset
当我将订单添加到产品的订单列表时,试图修复关联时(在新订单上设置产品导航属性)会崩溃

要崩溃的代码:

            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");
var product=context.CreateObject();
context.Products.AddObject(产品);
var order=context.CreateObject();
context.Orders.AddObject(order);
产品.订单.添加(订单);
if(order.Product!=产品)Console.WriteLine(“错误”);
例外情况:

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)
未处理System.Data.EntityException 消息=无法在实体类型System.Data.entity.DynamicProxies.Orders_A0290D8629F0336D278E5AEF2C0F2A91FF56726ED5E3A9FA668AC902696A8651上设置字段/属性产品。有关详细信息,请参见InnerException。 Source=System.Data.Entity 堆栈跟踪: 位于System.Data.Objects.Internal.PocopPropertyAccessorStrategy.SetNavigationPropertyValue(RelatedEnd RelatedEnd,对象值) 位于System.Data.Objects.Internal.EntityWrapper`1.SetNavigationPropertyValue(RelatedEnd RelatedEnd,对象值) 位于System.Data.Objects.DataClasses.EntityReference`1.AddToObject缓存(IEntityWrapper wrappedEntity) 在System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget、Boolean applyConstraints、Boolean AddRelationshipAsunched、Boolean relationshipAlreadyExists、Boolean AllowModifyingTheEndorRelationship、Boolean ForeignKeyChanges) 位于System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityRapper包装属性,布尔applyConstraints) 位于System.Data.Objects.DataClasses.EntityCollection`1.Add(TEntity实体) 在Program.cs中的proxy.CSharp.Program.Main(字符串[]args)处:第20行 位于System.AppDomain.\u nExecuteAssembly(RuntimeAssembly程序集,字符串[]args) 位于System.AppDomain.ExecuteAssembly(字符串汇编文件、证据汇编安全性、字符串[]args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()上 位于System.Threading.ThreadHelper.ThreadStart\u上下文(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx) 在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态) 位于System.Threading.ThreadHelper.ThreadStart()处 InnerException:System.NullReferenceException Message=对象引用未设置为对象的实例。 Source=Proxies.CSharp 堆栈跟踪: 在Orders.cs中的Proxies.CSharp.Orders.FixupProduct(Products-previousValue,Boolean-skipKeys)中 在Proxies.CSharp.Orders.set_Orders中的产品(产品值)。cs:第106行 位于System.Data.Entity.DynamicProxies.Orders_A0290D8629F0336D278E5AEF2C0F2A91FF56726ED5E3A9FA668AC902696A8651.SetBasePropertyValue(字符串,对象) at lambda_方法(闭包、对象、字符串、对象) 位于System.Data.Objects.Internal.EntityProxyFactory.TrySetBasePropertyValue(类型proxyType,字符串propertyName,对象实体,对象值) 在System.Data.Objects.Internal.EntityProxyFactory.c__DisplayClass8.b__7(对象实体,对象值) 位于System.Data.Objects.Internal.PocopPropertyAccessorStrategy.SetNavigationPropertyValue(RelatedEnd RelatedEnd,对象值) 注意:它适用于EntyObject,适用于自跟踪实体,如果密钥不是复合的或不可为null,它也适用


我是做错了什么还是真的有问题

我假设您正在使用poco实体慷慨器,或者正在进行类似的关系修复。如果是这样的话,那就是一个bug,而你做错了什么(也就是说,有一些方法可以做你想做的事情而不碰到所说的bug)

如果您使用:

order.Product = product;
而不是

product.Orders.Add(order);
它会做你想做的

问题在于Order对象的FixupProducts方法(或者更确切地说是它与productid setter的交互)。Fixup方法调用productid setter,setter将Product设置为null,当Fixup方法继续设置productid2时,尝试使用该产品时会出现null指针异常

当然,你也可以在其他情况下遇到类似的问题(尽管我现在想不出任何问题)。我相信,如果您查看生成的类,就可以找到合适的解决方案。我会毫不犹豫地说,在修正中跳过二传可以解决问题,但我还没有考虑到其中的含义,也没有测试过这一点,所以请自行承担风险

尝试替换:

productid = Product.productid;

productid2 = Product.productid2;


我必须纠正poco TT:

更改行(381441和475):

=。;
顺便说一句:

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

谢谢您的回复。我知道这个解决方法,但它正在寻找一个双向的解决方案。你的第二个建议似乎管用,我不知道为什么我一开始不试试;)我所有的单元测试都是绿色的,所以我想这是一个很好的更正。我想说你最好在发电机的网站上报告这个,然后检查并看到你已经做了。荣誉
<#=code.Escape(dependentProperty)#> = <#=code.Escape(navProperty)#>.<#=code.Escape(principalProperty)#>;
<#=code.FieldName(dependentProperty)#> = <#=code.Escape(navProperty)#>.<#=code.Escape(principalProperty)#>;