как вставить сущности, которые уже существуют в БД, в коллекцию родительской сущности и сохранить изменения - PullRequest
0 голосов
/ 22 марта 2012

Я новичок, поэтому я предполагаю, что в коде, который я собираюсь представить, будет много нарушений с точки зрения «правильного кода».(рад получить любое замечание ..)

У меня есть три объекта:

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', установил ее свойства со значениями, затем вставил в нее'Icollection' некоторые сущности 'AgeRange', которые я извлекаю из БД.(они уже существуют) Я добавляю новый '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;
    }

Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 23 марта 2014

Если вы используете репозитории с Autofac для автоматического создания экземпляров ваших Сервисов и / или репозиториев, вам следует зарегистрировать контекст следующим образом:

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

Это зарегистрирует контексткак единое целое;таким образом, вы всегда будете использовать один и тот же контекст во всех ваших сервисах или репозиториях.

0 голосов
/ 22 марта 2012

Эта ошибка возникает из-за того, что вы используете два разных контекста: один - чтение сущностей 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();

Теперь вся операция использует один и тот же контекст, и ваш код должен работать.

...