Что такое EntityReference

#c# #.net #entity-framework

#c# #.net #entity-framework

Вопрос:

Если я хочу связать два объекта Entity Framework person1 , person2 с отношением родитель-сын. Скажем, объекты из разных ObjectContexts или один отделен. Ну, а теперь я хотел бы написать что-то вроде:

person1.Parent = person2;

Это завершается ошибкой SaveChanges() . Итак, я пишу:

person1.ParentReference.EntityKey = person2.EntityKey;

Является ли это правильным решением для этой проблемы или всегда следует перезагружать «плохой» объект (объект, который в данный момент находится в другом ObjectContext )?

Комментарии:

1. Я не думаю, что вам следует устанавливать ссылку напрямую, это, вероятно, обходит некоторые элементы отслеживания. Пожалуйста, предоставьте подробную информацию о том, как происходит сбой на SaveChanges ?

Ответ №1:

Чтобы дать вам прямой ответ

Создайте свою таблицу

 [Tbl_Persons]

PersonId   int [PK]
ParentId   int [FK]
FirstName  nvarchar(100)
LastName   nvarchar(100)
CreateUser int
CreateDate datetime
UpdateUser int
UpdateDate datetime
  

У вас будет 2 варианта назначения родительского

 person1.Tbl_Persons = person2;
  

где person1 и person2 оба являются TblPersons объектами или просто присваивают идентификатор

 person1.ParentId = person2.PersonId;
  

Теперь, полный код, аналогичный тому, что я обычно делаю для вставки / обновления в базе данных

 public class MyRepository : IMyRepository
{
    MyEntities db = new MyEntities();
    DateTime now = DateTime.UTCNow;

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

    #region Update / Insert Persons

    public void UpdatePerson(Tbl_Persons person, int parentId, int userId)
    {
        // let's check if record is in db
        Tbl_Persons p = this.GetPersonById(person.PersonId); 
        if(p == null)
            p = new Person(); // person was not found in db

        p.FirstName = person.FirstName;
        p.LastName = person.LastName;

        // we can now hook up the parent object in 2 ways
        // or set the Id, or attach the hole object
        // NOTE: only choose one line!
        p.MyParent = parentId;
        p.TblParent = this.GetPersonById(parentId);

        // update info
        p.UpdateDate = now;
        p.UpdateUser = userId;


        if(p.PersonId == 0)
        {
            // is it new person in db, so we need to INSERT into the db
            p.CreateDate = now;
            p.CreateUser = userId;

            db.Tbl_Persons.AddObject(p);
        }
        else
        {
            // It's an existing person, we do need need to do anything
            // as internally once we assign a new value to the object that
            // come back from the database, EF sets Modified flag on this
        }

        // let's save
        this.Save();
    }

    #endregion

    #region Queries

        public Tbl_Persons GetPersonById(int personId)
        { 
            return db.Tbl_Persons.FirstOrDefault(x => x.PersonId == personId);
        }

    #endregion

}
  

в вашем контроллере:

 [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Tbl_Persons model, int parentId)
{
    if(ModelState.IsValid)
    {
        db.UpdatePerson(model, parentId, currentUserId);
    }

    return RedirectToAction("Index");
}
  

надеюсь, это поможет.