Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从MVC保存类之间的关联时出现实体框架错误_C#_Asp.net Mvc_Entity Framework - Fatal编程技术网

C# 从MVC保存类之间的关联时出现实体框架错误

C# 从MVC保存类之间的关联时出现实体框架错误,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我们将MVC与实体框架结合使用。 在某种程度上,我们正试图在两个实体之间建立联系。这在单元测试中可以正常工作,但从MVC控制器方法尝试时会出现以下错误: “保存不公开外部数据的实体时出错 关系的键属性。EntityEntries属性 将返回null,因为无法将单个实体标识为 异常的来源。可以在保存时处理异常 通过在实体类型中公开外键属性使其更容易。” (精简)类别: 通过的单元测试: [TestMethod] public void LinkOrganizationToPositionT

我们将MVC与实体框架结合使用。 在某种程度上,我们正试图在两个实体之间建立联系。这在单元测试中可以正常工作,但从MVC控制器方法尝试时会出现以下错误:

“保存不公开外部数据的实体时出错 关系的键属性。EntityEntries属性 将返回null,因为无法将单个实体标识为 异常的来源。可以在保存时处理异常 通过在实体类型中公开外键属性使其更容易。”

(精简)类别:

通过的单元测试:

    [TestMethod]
public void LinkOrganizationToPositionTest()
{
    // arrange
    DbModel dbModel;
    Organization org;
    Position pos;
    Guid orgId;

    using (dbModel = new DbModel())
    {
        dbModel.Database.Delete();
        dbModel.Database.Create();

        // - first organization
        org = dbModel.Organizations.Create();
        org.Name = "TestOrgFirst";
        dbModel.Entry(org).State = EntityState.Added;

        pos = dbModel.Positions.Create();
        pos.Function = "TestFunc";
        dbModel.Entry(pos).State = EntityState.Added;

        // - link pos to first org
        pos.Organization = org;

        org = dbModel.Organizations.Create();
        org.Name = "TestOrgSecond";
        dbModel.Entry(org).State = EntityState.Added;
        orgId = org.Id;
        dbModel.SaveChanges();
    }

    // act
    // - obtain "fresh" model
    using (dbModel = new DbModel())
    {
        // - get second org
        org = dbModel.Organizations.Find(orgId);
        pos = dbModel.Positions.Find(pos.Id);
        pos.Organization = org;
        dbModel.SaveChanges();
    }

    // assert
    using (dbModel = new DbModel())
    {
        Position actual =
            dbModel.Positions
                .Include("Organization")
                    .First(x => x.Id.Equals(pos.Id));
        // - link was saved 
        Assert.AreEqual(
            "TestOrgSecond", 
            actual.Organization.Name
            );
    }
}
为什么MVC需要OrganizationId外键属性?
是否有一个简单的修复程序不需要模型中的所有外键?

我可以衷心建议显式实现外键。它让生活变得更简单!只是好奇。你是否尝试过将职位添加到组织的联系人中?@ilmatte:是的,我甚至尝试过在Organi中向集合添加职位组织的组织化和设置Position@Dabblernl:我可以这样看,但这比丑陋更糟糕:OO实现不应该需要关系外键。@kc了解外键关联与独立关联(没有原始FK属性)的优势。无论从哪个角度看,EF类模型仍然是DAL,因此请针对其主要职责对其进行优化。您已经有了主键、基类
实体
、嵌套映射类。原始FKs不会让它变得更“糟糕”:
    [HttpPost]
public ActionResult Edit(Position position, string organizationId = "")
{
    if (!ModelState.IsValid)
    {
        return View(position);
    }
    db.Entry(position).State = EntityState.Modified;
    if (!string.IsNullOrEmpty(organizationId))
    {
        Guid orgId = Guid.Parse(organizationId);
        Organization organization =
            db.Organizations
                .First(x => x.Id.Equals(orgId));
        position.Organization = organization;
    }
    db.SaveChanges();
    RedirectToAction("Index");
}
    [TestMethod]
public void LinkOrganizationToPositionTest()
{
    // arrange
    DbModel dbModel;
    Organization org;
    Position pos;
    Guid orgId;

    using (dbModel = new DbModel())
    {
        dbModel.Database.Delete();
        dbModel.Database.Create();

        // - first organization
        org = dbModel.Organizations.Create();
        org.Name = "TestOrgFirst";
        dbModel.Entry(org).State = EntityState.Added;

        pos = dbModel.Positions.Create();
        pos.Function = "TestFunc";
        dbModel.Entry(pos).State = EntityState.Added;

        // - link pos to first org
        pos.Organization = org;

        org = dbModel.Organizations.Create();
        org.Name = "TestOrgSecond";
        dbModel.Entry(org).State = EntityState.Added;
        orgId = org.Id;
        dbModel.SaveChanges();
    }

    // act
    // - obtain "fresh" model
    using (dbModel = new DbModel())
    {
        // - get second org
        org = dbModel.Organizations.Find(orgId);
        pos = dbModel.Positions.Find(pos.Id);
        pos.Organization = org;
        dbModel.SaveChanges();
    }

    // assert
    using (dbModel = new DbModel())
    {
        Position actual =
            dbModel.Positions
                .Include("Organization")
                    .First(x => x.Id.Equals(pos.Id));
        // - link was saved 
        Assert.AreEqual(
            "TestOrgSecond", 
            actual.Organization.Name
            );
    }
}