【问题标题】:Entity Framework 'An item cannot be removed from a fixed size Array of type *[]'实体框架'无法从* []类型的固定大小数组中删除项目'
【发布时间】:2011-04-05 19:58:30
【问题描述】:

我正在使用 EntityFramework 来持久化我的实体。

我遇到的问题是,当通过 WCF 发送在 Silverlight 中构建的实体以进行持久化时,我收到错误“无法从类型为“CarterShop.Commerce.Entities.ManufacturedItemRequirement[]”的固定大小数组中删除项目.

我正在插入一个具有 ManufacturedItemRequirements 的 ICollection 的实体 (ManufacturedItem)。实体框架应该允许我将它作为 POCO 对象“添加”到 DbContext 并将其持久化,但由于某种原因它抱怨集合。

以前有人遇到过这个问题吗?基本上我不知道它在抱怨什么。错误来自 System.Data 内部:

at System.Data.Objects.Internal.PocoPropertyAccessorStrategy.CollectionRemove(RelatedEnd relatedEnd, Object value)
   at System.Data.Objects.Internal.EntityWrapper`1.CollectionRemove(RelatedEnd relatedEnd, Object value)
   at System.Data.Objects.DataClasses.EntityCollection`1.RemoveFromObjectCache(IEntityWrapper wrappedEntity)
   at System.Data.Objects.ObjectStateManager.DegradePromotedRelationships()
   at System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
   at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
   at System.Data.Entity.Internal.Linq.InternalSet`1.<>c__DisplayClass5.<Add>b__4()
   at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
   at System.Data.Entity.DbSet`1.Add(TEntity entity)
   at Commerce.Model.Repositories.RepositoryBase`1.Add(T entity) in C:\OclProjects 4.1\CarterShop\CarterShop.Commerce.Model\Repositories\RepositoryBase.cs:line 28
   at CarterShop.Commerce.Services.Implementation.StockItemService.CreateManufacturedItem(ManufacturedItem manufactedItem, Boolean createDefinitionAswell) in C:\OclProjects 4.1\CarterShop\CarterShop.Commerce.Services\Implementation\StockItemService.cs:line 137

我基本上在做:

ManufacturedItem item = new ManufacturedItem();
item.ManufacturedItemRequirements.Add(new ManufacturedItemRequirement() { Quantity = 1; DefinitionId = 5 });

// Send to WCF...

Context.ManufacturedItems.Add(item); // Error thrown here.
Context.SaveChanges();

【问题讨论】:

  • 您添加的项目是否与其他项目有关系?看起来添加意味着从另一个集合中删除。
  • 它应该是一个全新的项目。添加描述。
  • 服务器端反序列化后item的ManufactureItemRequirement集合是什么类型?
  • 它是一个数组,这就是为什么不能从中删除东西的原因,它是只读的。但我不明白为什么 EF 试图删除它?如果我能断点 System.Data.Objects...

标签: .net silverlight wcf entity-framework


【解决方案1】:

还有其他情况会遇到此错误,包括删除通过使用.Include 扩展方法获得的实体时。

关键是如果关系被定义为ICollection&lt;T&gt;,那么实体框架将通过使用数组来实现关系。但是,您可以为关系选择许多有效类型,包括 ISet&lt;T&gt;IList&lt;T&gt; 类型。使用其中任何一个来定义您的关系都可以解决问题。

【讨论】:

  • 我不确定您的答案是否解决了原始问题,但它帮助我解决了使用 DbSet.Local 集合时触发的类似错误。
  • 为什么数组与ICollection接口,即使它不支持remove()?
  • @Worthy7 我不确定我是否听懂了你的问题。 [] 语法适用于实现 this[...] 索引器的任何集合类型。也许你应该问一个新的 SO 问题?
【解决方案2】:

这是因为创建的默认 EF 类被视为 HashSet,并且关系被表示为 ICollection 类型。如果您在构造函数中打开生成的类,对于相关对象列表,请附加一个 ToList() 方法,如下所示: 公共结果集() { this.Results = new HashSet().ToList(); // 添加了 ToList() ...... }

然后你会在下面的某个地方看到它被定义为公共虚拟财产的地方,如下所示: 公共虚拟 ICollection 结果 { 获取;放; } 从 ICollection 更改为 List

...这解决了我遇到的类似问题...但是您必须注意,如果您从数据库重新生成类/模型,您的代码将被覆盖

【讨论】:

    【解决方案3】:

    我正在插入以下图表:

    ManufacturedItem has many ManufacturedItemRequirements.
    ManufacturedItemRequirement has a ManufacturedItem.
    ManufacturedItemRequirement has a StockItemDefinition.
    

    这很满意。但是,我正在查看图表的一部分:

    StockItemDefinition has many ManufacturedItemRequirements.
    

    因为我没有用新的 ManufacturedItemRequirement 填充这个引用数组,所以它不起作用。

    我确实认为我不应该指定这一点,因为这种关系是隐式而不是显式的关系。我认为与其为这些属性生成一个空数组,不如生成 NULL。如果我将子数组设置为 NULL,则添加操作有效。

    如果我设法改变它的序列化方式,我会通知你。

    【讨论】:

    • 我搬回了自我跟踪实体以摆脱这一切。我认为 POCO 对象不值得麻烦,尤其是现在我已经尝试了这两种方法。
    【解决方案4】:

    对于乘以乘实体关联映射:

    item *>|------|<* ManufacturedItemRequirement
    

    然后将在 item 实体和 ManufacturedItemRequirement 中创建导航属性,命名为 item.ManufacturedItemRequirements 和 ManufacturedItemRequirement.items。

    新创建的 ManufacturedItemRequirement 应该首先插入到实体表中以获取 ID

    var mf = new ManufacturedItemRequirement() { Quantity = 1; DefinitionId = 5 };
    Context.ManufacturedItemRequirement.Add(mf);
    Context.SaveChanges();
    //then add the association to item
    item.ManufacturedItemRequirements.Add(mf);
    Context.SaveChanges();
    

    如果您检查数据库结构,则会创建一个 ID 映射表,用于记录 Items 和 ManufacturedItemRequirements 之间的关系。实体对象的 ID 是建立关联所必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多