我正在使用EntityFramework来保存我的实体。
我遇到的问题是,当通过WCF发送在Silverlight中构建的实体被持久化时,我收到错误“无法从固定大小的数组中删除项目'CarterShop.Commerce.Entities.ManufacturedItemRequirement []'
我正在插入一个实体(ManufacturedItem),其中ICollection为ManufacturedItemRequirements。实体框架应该允许我将其作为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();
答案 0 :(得分:4)
在其他情况下,您会遇到此错误,包括删除通过.Include
扩展程序获取的实体时。
关键是如果关系被定义为ICollection<T>
,那么实体框架将通过使用数组来实现关系。但是,您可以从关系中选择许多有效类型,包括ISet<T>
和IList<T>
类型。使用其中任何一个来定义您的关系都可以解决问题。
答案 1 :(得分:2)
原因是创建的默认EF类被视为HashSet,关系表示为ICollection类型。如果在构造函数中打开生成的类,则对于相关对象列表,请添加ToList()方法,如下所示: public ResultSet() { this.Results = new HashSet()。ToList(); //添加了ToList() ..... }
然后在下面的某处你将看到它被定义为公共虚拟财产的位置,如下所示: 公共虚拟ICollection结果{get;组; } 从ICollection更改为List
...这解决了我遇到的类似问题......但是你必须注意,如果从数据库重新生成类/模型,你的代码将被覆盖
答案 2 :(得分:0)
我插入了以下图表:
ManufacturedItem has many ManufacturedItemRequirements.
ManufacturedItemRequirement has a ManufacturedItem.
ManufacturedItemRequirement has a StockItemDefinition.
这很满意。但是我在看图的一部分是:
StockItemDefinition has many ManufacturedItemRequirements.
因为我没有使用新的ManufacturedItemRequirement填充此引用数组,所以它不起作用。
我认为我不应该指定这个,因为这种关系是一种隐含而非显性的关系。我认为它不应该为这些属性生成一个空数组,而应该生成NULL。如果我将子数组设置为NULL,则Add操作可以正常工作。
如果我设法改变序列化的方式,我会通知你。
答案 3 :(得分:0)
对于乘法乘法实体关联映射:
item *>|------|<* ManufacturedItemRequirement
然后将在item entity和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来建立关联。