【问题标题】:"Fixed size array" error on insert One-To-Many插入一对多时出现“固定大小数组”错误
【发布时间】:2018-04-01 10:54:49
【问题描述】:

我正在使用 EF6 进行一个小项目。每当我想用OneToManyManyToMany 属性插入一些数据时,都会遇到错误:

InvalidOperationException:无法将项目添加到“Shared.ProjectStep[]”类型的固定大小数组中

我搜索了一下,发现建议用IList 替换导航属性上的ICollection 以及通过Add Service Reference 更改序列化,但这些都不起作用。

我的实体(省略了一些字段,因为它们不应该造成问题):

[DataContract(Namespace = "Shared")]
public class Project
{

    public Project()
    {
        this.ProjectSteps = new List<ProjectStep>();
    }

    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public virtual IList<ProjectStep> ProjectSteps { get; set; }
}

[DataContract(Namespace = "Shared")]
public class ProjectStep
{
    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public Project Project { get; set; }
}

我通过Fluent API定义了如下关系:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Project>().HasMany<ProjectStep>(p => p.ProjectSteps).WithRequired(ps => ps.Project).Map(m => m.MapKey("Project"));
}

我有一个PMSDatabaseConnector,它将操作委托给我的PMSContext : DbContext

这个上下文是用

创建的
public PMSContext() : base(nameOrConnectionString: "PmsDb")
{
    this.Configuration.ProxyCreationEnabled = false;
    this.Configuration.LazyLoadingEnabled = false;
}

最后是我插入ProjectStep的方法

public void InsertProjectStep(ProjectStep ps)
{
    this.projectSteps.Add(ps);
    this.SaveChanges();
}

每当我现在执行时

ProjectStep ps = new ProjectStep();
ps.Description = "test";
ps.EndDate = new DateTime();
ps.Project = service.FindProjectById(8);
ps.StartDate = new DateTime();
service.InsertProjectStep(ps);

(创建一个新的ProjectStep,设置一些字段以及连接到Project),我得到了异常

InvalidOperationException:无法将项目添加到固定大小 'Shared.ProjectStep[]' 类型的数组。

添加这一行

this.projects.Find(ps.Project.ID).ProjectSteps.Add(ps);

作为InsertProjectStep 方法的第一行,如下所示:

public void InsertProjectStep(ProjectStep ps)
{
    this.projects.Find(ps.Project.ID).ProjectSteps.Add(ps);
    this.projectSteps.Add(ps);
    this.SaveChanges();
}

,我得到了错误

'违反了多重性约束。角色 关系的“Project_ProjectSteps_Source” 'PMSDatabaseConnector.Project_ProjectSteps' 具有多重性 1 或 0..1.'

我真的迷失了这个话题。我尝试了我能找到的一切,但没有解决第一个错误。

谁能帮我理解为什么会出现这些错误,以及如何解决它们?

【问题讨论】:

  • 为什么 ProjectSteps 是 IList,而不是 ICollection?
  • @DevilSuichiro 在问题 op 中指出“我用 Google 搜索了一下,发现建议用 IList 替换导航属性上的 ICollection”
  • @DevilSuichiro 我从ICollection开始,但由于谷歌搜索该特定错误,我将其更改为IList,但没有帮助。
  • 如果将 .Map 函数替换为 .HasForeignKey 函数进行映射(或根本没有进一步映射)会发生什么?
  • @DevilSuichiro 如果我更改映射,那么我什至无法从数据库中检索Project

标签: c# .net entity-framework wcf


【解决方案1】:

虽然对 EF 集合导航属性的一般建议是使用 ICollection&lt;T&gt; 类型,但它不适用于 WCF 序列化,因为它允许 WCF 反序列化器分配 T[]IList&lt;T&gt; 相同(T[]“实现”两个接口以及许多其他接口)。

解决办法是不使用接口,而是具体输入List&lt;T&gt;:

[DataMember]
public virtual List<ProjectStep> ProjectSteps { get; set; }

另一种需要更多编码的方法是使用显式支持字段:

private ICollection<ProjectStep> projectSteps;

[DataMember]
public virtual ICollection<ProjectStep> ProjectSteps
{
    get { return projectSteps; }
    set { projectSteps = value is ProjectStep[] ? value.ToList() : value; }
}

【讨论】:

  • 这似乎可行,但现在我在this.projectSteps.Add(ps); 上收到Multiplicity constraint violated。插入方法理论上对吗?
  • 请在每个帖子中提出一个问题。无论如何,这些都是相互排斥的。如果你做this.projects.Find(ps.Project.ID).ProjectSteps.Add(ps);,那么不要做this.projectSteps.Add(ps);。反之亦然。如果ps.Project 实例未附加到上下文,我建议使用第一种方法(this.projects.Find(ps.Project.ID).ProjectSteps.Add(ps);)。
猜你喜欢
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 2019-05-11
  • 2018-11-19
  • 1970-01-01
  • 2021-10-03
相关资源
最近更新 更多