简体   繁体   English

无法使用Entity Framework更新对象内的复杂属性

[英]Cannot update a complex property inside my object with Entity Framework

I have an object A that has another object B inside. 我有一个对象A,里面有另一个对象B. I am loading the using EntityFramework and modifying the object B but when I set the State to EntityState.Modified I have this error {"An entity object cannot be referenced by multiple instances of IEntityChangeTracker."} 我正在加载使用EntityFramework并修改对象B但是当我将State设置为EntityState.Modified我有这个错误{"An entity object cannot be referenced by multiple instances of IEntityChangeTracker."}

This are my objects 这是我的目标

public class Patient : IEntity, IObjectWithState
{
    public virtual int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsMobileActived { get; set; }

    public virtual MobilePatient MobilePatient { get; set; }

    [NotMapped]
    public State State { get; set; }
}

public class MobilePatient : IObjectWithState
{
    public virtual int Id { get; set; }
    public virtual int PatientPin { get; set; }
    public virtual string SecurityAnswer { get; set; }
    public virtual bool IsPinRemembered { get; set; }
    public virtual PhysiologicalData PhysiologicalData { get; set; }

    [NotMapped]
    public State State { get; set; }
}

I have a repository and a unit of work and bascally using it I am loading the Patient object in this way. 我有一个存储库和一个工作单元并且基本上使用它我以这种方式加载Patient对象。

...   Patient patient = context.Patients.Find(id); ...

Then with the patient I am updating the MobilePatient 然后与患者我正在更新MobilePatient

... patient.MobilePatient = NEWmobilePatient; ...

and then updating it with 然后用它更新它

PatientContext patientContext = (PatientContext)context;
patientContext.Entry(patient).State = EntityState.Modified;

My context only has the Patient dbset 我的上下文只有Patient dbset

public class PatientContext:BaseContext<PatientContext>, IPatientContext
{
    public IDbSet<Patient> Patients { get; set; }

    public void SetModified(object entity)
    {
       Entry(entity).State = EntityState.Modified;
    }

    public void SetAdd(object entity)
    {
        Entry(entity).State = EntityState.Added;
    }
}

So I dont know what I am missing to update. 所以我不知道我缺少什么来更新。 When I am loading the Patient I am using the default lazy-load but how I have data in MobilePatient I am getting that object too. 当我正在加载患者时,我使用的是默认的延迟加载,但我在MobilePatient中的数据如何,我也得到了该对象。

Something that I think could be a good information is that I am using unit of work and repository and my application a disconnect application. 我认为可能是一个很好的信息是我正在使用工作单元和存储库以及我的应用程序断开连接应用程序。

This my repository: 这个我的存储库:

public class PatientRepository : IRepository<Patient>
    {
        private IPatientContext context=new PatientContext();

        public PatientRepository(PatientContext context)
        {
            this.context = context;
        }

        public void Add(Patient patient)
        {
             context.SetAdd(patient);
        }

        public void Update(Patient patient)
        {
           context.SetModified(patient);
        }

        public void Delete(Patient entity)
        {
            throw new NotImplementedException();
        }

        public Patient FindById(int id)
        {

            Patient patient = context.Patients.Find(id);
            return patient;
        }

        public IQueryable<Patient> Find(Expression<Func<Patient, bool>> predicate)
        {
           PatientContext patientContext = (PatientContext)context;
           return patientContext.Set<Patient>().Where(predicate).AsQueryable<Patient>();
        }

        public IQueryable<Patient> FindAll()
        {
            return context.Patients;
        }
    }

I an this how I am using it in my services : 我这是我如何在我的服务中使用它:

Patient patient = new Patient();
using (IPatientLoaderService patientLoaderService = AppManager.Instance.Database.CreatePatientLoaderService())
    {
       patient = patientLoaderService.LoadPatientById(patientId);
    }


patient.MobilePatient =New_mobilePatient;
patient.State = State.Modified;
patient.Age = 40;
using (IPatientUpdaterService patientUpdaterService = AppManager.Instance.Database.CreatePatientUpdaterService())
        {
            patientUpdaterService.UpdatePatient(patient);
        }

In my services I use the unit of work and the repositories this is one of my services used in the code: 在我的服务中,我使用工作单元和存储库,这是我在代码中使用的服务之一:

public class EntityFrameworkPatientUpdaterService: IPatientUpdaterService
    {
        private   PatientRepository patientsRepository;
        private   EntityFrameworkUnitOfWork<PatientContext> unitOfWork;
        public EntityFrameworkPatientUpdaterService()
        {
            unitOfWork = new EntityFrameworkUnitOfWork<PatientContext>();
            PatientContext patientContent = new PatientContext();
            patientsRepository = new PatientRepository(patientContent);
        }

        public void UpdatePatient(Patient patient)
        {   try
            {
                patientsRepository.Update(patient);
                unitOfWork.Commit();
            }
            catch (Exception e)
            {
                //TODO: Log the error and evoid to throw another exception-DOR
                unitOfWork.Dispose();
                throw new Exception("Error on EntityFrameworkPatientUpdaterService.UpdatePatient. " +
                                     e.Message);
            }
            finally
            {
                unitOfWork.Dispose();
                unitOfWork = new EntityFrameworkUnitOfWork<PatientContext>();
                PatientContext patientContent = new PatientContext();
                patientsRepository = new PatientRepository(patientContent);
            }
        }

        public void Dispose()
        {
            unitOfWork.Dispose();
        }
}

Thank you for read this post 感谢您阅读这篇文章

I am going to be adding more detail on how I am currently using my service. 我将添加有关我目前如何使用我的服务的更多详细信息。 I think the problem is that I am trying to use tghe Onion Architecture and I am missing something. 我认为问题在于我正在尝试使用洋葱架构而我错过了一些东西。

public class PatientContext:BaseContext<PatientContext>, IPatientContext
    {
        public IDbSet<Patient> Patients { get; set; }
        public void SetModified(object entity)
        {
           Entry(entity).State = EntityState.Modified;
        }

    }

    public class PatientRepository : IRepository<Patient>
    {
        private readonly IPatientContext context;

        public PatientRepository(PatientContext context)
        {
            this.context = context;
        }


        public void Update(Patient patient)
        {
          context.SetModified(_patient);

        }

        public Patient FindById(int id)
        {

            Patient patient = context.Patients.Find(id);
            return patient;
        }
    }

    public class EntityFrameworkPatientUpdaterService
    {
        private   PatientRepository patientsRepository;
        private   EntityFrameworkUnitOfWork<PatientContext> unitOfWork;
        public EntityFrameworkPatientUpdaterService()
        {
            unitOfWork = new EntityFrameworkUnitOfWork<PatientContext>();
            PatientContext patientContent = new PatientContext();
            patientsRepository = new PatientRepository(patientContent);
        }

        public void UpdatePatient(Patient patient)
        {   try
            {
                patientsRepository.Update(patient);
                unitOfWork.Commit();
            }
            catch (Exception e)
            {
                //TODO: Log the error and evoid to throw another exception-DOR
                unitOfWork.Dispose();
                throw new Exception("Error on EntityFrameworkPatientUpdaterService.UpdatePatient. " +
                                     e.Message);
            }
            finally
            {
                unitOfWork.Dispose();
            }
        }

        public void Dispose()
        {
            unitOfWork.Dispose();
        }
    }

    //GEtting the patient and dispose everything,
     Patient patient = new Patient();
            using (IPatientLoaderService patientLoaderService = AppManager.Instance.Database.CreatePatientLoaderService())
            {
                patient = patientLoaderService.LoadPatientById(patientId);
            }
    //THEN Calling my services to update
     using (IPatientUpdaterService patientUpdaterService = AppManager.Instance.Database.CreatePatientUpdaterService())
            {
                patientUpdaterService.UpdatePatient(patient);
            }

If I interpret the exception message correctly, it means that you have two contexts, and both want the entry of your entity. 如果我正确解释了异常消息,则意味着您有两个上下文,并且都希望输入您的实体。 This is not possible, only one context at the time can deal with a data row at a time. 这是不可能的,当时只有一个上下文可以一次处理数据行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM