0

我是一个新手,所以我想在我将要介绍的代码中,在“正确代码”方面会有很多违规行为。(很高兴得到任何评论..)

我有三个实体:

public class Person
{
    public int PersonId { get; set; }
    public int AgeId { get; set; }
    ...//some properties
}

public class Age
{
    public int AgeId { get; set;}
    public int PersonsId { get; set; }

    ...//some properties

    public virtual ICollection<AgeRange> AgeRanges {get; set;}

}


public class AgeRange
{
    public string AgeRangeId { get; set; }
    public string Value { get; set; }

    ICollection<Age> Ages { get; set; }

}

我创建了一个新的“Age”实体,用值设置它的属性,然后将一些“AgeRange”实体插入到它的“Icollection”中,这些实体是我从 DB 中提取的。(它们已经存在)我将新的“Age”添加到 dbContex,当执行“savechanges”时出现异常:

Violation of PRIMARY KEY constraint 'PK_AgeRanges'. Cannot insert duplicate key in  object 'dbo.AgeRanges'.
The statement has been terminated. 

(AgeRange PK 是故意为字符串的,因为我的目的是在逻辑基础上保持它们不变)

这是其余的代码:

[HttpPost]
public ActionResult AddPerson(AddPersonViewModel vm)
 {

         if (ModelState.IsValid)
         {   
             Services services = new Services();
             Age age = services.GetAgeEntity(vm.Ages); 
             db.Ages.Add(age);
             db.SaveChanges(); //exception apears here.
             ........

         }

public class Services
{
    ModelContext db;

    public Services()
    {
        db = new ModelContext();
    }

    public Age GetAgeEntity(string[] ages)
    {
        Age age = new Age();

        //some more code...

        age.AgeRanges = GetAgeRanges(ages);   
        return age;
    }

        }



    ICollection<AgeRange> GetAgeRanges(string[] ages)
    {
        Age age = new Age();
        age.AgeRanges = new List<AgeRange>();

        foreach (string item in ages)
        {
            var ageRange = db.AgeRanges.Find(item);
            age.AgeRanges.Add(ageRange);
        }

        return age.AgeRanges;
    }

任何帮助将不胜感激。

4

2 回答 2

1

如果您使用带有 Autofac 的存储库来自动创建服务和/或存储库的实例,那么您应该像这样注册上下文

builder.RegisterInstance<IMyContext>(new MyContext("MyContext"));

这会将上下文注册为单个实例;因此,您将始终在所有服务或存储库中使用相同的上下文。

于 2014-03-22T22:36:54.600 回答
0

您遇到此错误是因为您使用了两种不同的上下文:一种是AgeRange从数据库中读取实体:它是您在构造函数中创建ModelContext db的类中的私有成员:Services

db = new ModelContext();

第二个上下文将Age实体与AgeRange您在控制器操作中使用的集合一起添加:

db.Ages.Add(age);

这不能是同一个db实例。第二个上下文对实体一无所知,AgeRange因为它们已在另一个上下文中加载。因此SaveChanges尝试将它们作为新实体插入。

你可以在你的Services类中创建两个额外的方法:

public void AddAgeEntity(Age age)
{
    db.Ages.Add(age);
}

public void SaveChanges()
{
    db.SaveChanges();
}

在你的控制器中:

Services services = new Services();
Age age = services.GetAgeEntity(vm.Ages); 
services.AddAgeEntity(age);
services.SaveChanges();

现在整个操作使用相同的上下文,您的代码应该可以工作。

于 2012-03-22T19:33:42.463 回答