首先更新 Mvc 代码中的值对象字段

Update Value Object fileld in Mvc code First

我有一个名为 Validity 的值对象及其属性 StartDate 和 EndDate。 我有更新这个 field.but 得到一些 error.The 错误是:

InvalidOperationException: 实体类型 'Validity' 具有定义导航,当前未跟踪提供的实体。要开始跟踪此实体,请在所有者条目上调用“.Reference().TargetEntry”。

如何解决这个错误?

我的代码是:

public async Task<Subscription> Update(string ID, bool Active, string Plan, string Periodicity, decimal Price, string LocationTargets, string paymentStatus,
            DateTime startDate, DateTime endDate, string OperationType)
        {
            #region PaymentStatus
            int EnumPaymentStatus = 0;
            string[] values = Enum.GetNames(typeof(PaymentStatusEnum.PaymentStatus));

            if (values[0] == paymentStatus)
            {
                EnumPaymentStatus = (int)PaymentStatus.Due;
            }
            else if (values[1] == paymentStatus)
            {
                EnumPaymentStatus = (int)PaymentStatus.Open;
            }
            else if (values[2] == paymentStatus)
            {
                EnumPaymentStatus = (int)PaymentStatus.UnPaid;
            }
            else if (values[3] == paymentStatus)
            {
                EnumPaymentStatus = (int)PaymentStatus.Paid;
            }
            #endregion

            #region Periodicity
            int EnumPeriodicityValue = 0;
            string[] values1 = Enum.GetNames(typeof(PeriodicityEnum.EnumPeriodicity));

            if (values1[0] == Periodicity)
            {
                EnumPeriodicityValue = (int)EnumPeriodicity.Monthly;
            }
            else if (values1[1] == Periodicity)
            {
                EnumPeriodicityValue = (int)EnumPeriodicity.Trimestral;
            }
            else if (values1[2] == Periodicity)
            {
                EnumPeriodicityValue = (int)EnumPeriodicity.Semestral;
            }
            else if (values1[3] == Periodicity)
            {
                EnumPeriodicityValue = (int)EnumPeriodicity.Annual;
            }
            #endregion

            #region Operation Type
            int OperationTypeValue = 0;
            string[] values2 = Enum.GetNames(typeof(OperationTypeEnum.EnumOperationType));

            if (values2[0] == OperationType)
            {
                OperationTypeValue = (int)EnumOperationType.NewSubscription;
            }
            else if (values2[1] == OperationType)
            {
                OperationTypeValue = (int)EnumOperationType.SubscriptionRenewal;
            }
            else if (values2[2] == OperationType)
            {
                OperationTypeValue = (int)EnumOperationType.SubscriptionCancellation;
            }
            else if (values2[3] == OperationType)
            {
                OperationTypeValue = (int)EnumOperationType.SubscriptionChange;
            }
            #endregion

            #region Update Data in Subscription Table
            var subscription = new Subscription()
            {
                ID = ID,
                Active = Active,
                Plan = Plan,
                Periodicity = Convert.ToString(EnumPeriodicityValue),
                Price = Price,
                LocationTargets = LocationTargets,
                PaymentStatus = Convert.ToString(EnumPaymentStatus),
                OperationType = Convert.ToString(OperationTypeValue),
                UpdatedAt = DateTime.UtcNow
            };
            subscription.Validity = new Validity(startDate, endDate);
            //Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<Subscription> s = await _db.AddAsync(subscription);



            _db.Entry(subscription).Property(x => x.Active).IsModified = true;
            _db.Entry(subscription).Property(x => x.Plan).IsModified = true;
            _db.Entry(subscription).Property(x => x.Periodicity).IsModified = true;
            _db.Entry(subscription).Property(x => x.Price).IsModified = true;
            _db.Entry(subscription).Property(x => x.LocationTargets).IsModified = true;
            _db.Entry(subscription).Property(x => x.PaymentStatus).IsModified = true;

            _db.Entry(subscription.Validity).Property(x => x.StartDate).IsModified = true;
            _db.Entry(subscription.Validity).Property(x => x.EndDate).IsModified = true;



            _db.Entry(subscription).Property(x => x.OperationType).IsModified = true;
            _db.Entry(subscription).Property(x => x.UpdatedAt).IsModified = true;

            #endregion

            #region Insert Data in SubscriptionHistory Table

            string a = Convert.ToString(GuidComb.Generate());
            var subscriptionhistory = new SubscriptionHistory()
            {
                ID = a,
                Active = Active,
                Plan = Plan,
                Periodicity = Convert.ToString(EnumPeriodicityValue),
                Price = Price,
                LocationTargets = LocationTargets,
                PaymentStatus = Convert.ToString(EnumPaymentStatus),
                OperationType = Convert.ToString(OperationTypeValue)
            };
            subscriptionhistory.Validity = new Validity(startDate, endDate);

            Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<SubscriptionHistory> y = await _db.AddAsync(subscriptionhistory);

            #endregion

            await _db.SaveChangesAsync();
            return subscription;
        }


In Subscription Class:
 public class Subscription: BaseEntity
    {
        public Subscription()
        {
            this.ID = Convert.ToString(System.Guid.NewGuid());
            this.CreatedAt = DateTime.UtcNow;
            this.IsCancel = false;
        }

        private List<Validity> validities = new List<Validity>();

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [MaxLength(128)]
        public string ID { get; set; }

        public bool Active { get; set; }

        [MaxLength(150)]
        public string Plan { get; set; }

        [MaxLength(101)]
        public string Periodicity { get; set; }

        public decimal Price { get; set; }

        [MaxLength(250)]
        public string LocationTargets { get; set; }

        [MaxLength(101)]
        public string PaymentStatus { get; set; }

        public Validity Validity { get; set; }

        [MaxLength(101)]
        public string OperationType { get; set; }

        public bool IsCancel { get; set; }

        public DateTime CreatedAt { get; set; }

        public DateTime UpdatedAt { get; set; }

        public DateTime DeletedAt { get; set; }

        public bool Deleted { get; set; }

        //private List<Validity> validities = new List<Validity>();

        public void Assignvalidity(Validity validitys)
        {
            this.validities.Add(validitys);
        }

    }

In Validity Class:

 public class Validity : ValueObject
    {
        public DateTime StartDate { get; private set; }
        public DateTime EndDate { get; private set; }

        private Validity() { }

        public Validity(DateTime  startdate, DateTime enddate)
        {
            StartDate = startdate;
            EndDate = enddate;
        }

        protected override IEnumerable<object> GetAtomicValues()
        {
            yield return StartDate;
            yield return EndDate;
        }

    }

为了更新一个实体,它必须被实体跟踪,在你下面的代码中你正在创建新对象:

var subscription = new Subscription()
            {
                ID = ID,
                Active = Active,
                Plan = Plan,
                Periodicity = Convert.ToString(EnumPeriodicityValue),
                Price = Price,
                LocationTargets = LocationTargets,
                PaymentStatus = Convert.ToString(EnumPaymentStatus),
                OperationType = Convert.ToString(OperationTypeValue),
                UpdatedAt = DateTime.UtcNow
            };

首先需要从数据库中获取该实体,然后更新相关字段并保存到数据库;

[更新]

有效性是与订阅相关的实体,因此您需要一个包含查询从数据库中获取对象,然后您可以更新和保存。

var subscription = _db.Set<Subscription>().Single(x=>x.ID == ID).Include(x=>x.Validity);

subscription.Validity.StartDate = startDate;
subscription.Vaklidity.EndDate = endDate;

_db.SaveChanges();

[更新]

添加外键属性然后创建新迁移然后更新数据库:

public class Validity : ValueObject
    {
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }

        public string SubscriptionID { get; set; }
        public Subscription Subscription { get; set; }

        // ...
    }

public class Subscription: BaseEntity
    {
        public string ValidityID { get; set; }
        public Validity Validity { get; set; }

        // ...
    }

更新db后,获取相关Validity实体并更新:

var validity = _db.Set<Validity>().Find(x => x.SubscriptionID == ID);

validity.StartDate = startDate;
validity.EndDate = endDate;

_db.SaveChanges();

添加这一行: Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry s = _db.Update(订阅);

在这一行之后: subscription.Validity = 新有效期(开始日期,结束日期);