【问题标题】:Update Value Object fileld in Mvc code First首先更新 Mvc 代码中的值对象字段
【发布时间】:2019-05-03 05:16:26
【问题描述】:

我有一个名为 Validity 的值对象及其属性 StartDate 和 EndDate。 我已更新此字段。但出现一些错误。错误是:

InvalidOperationException:实体类型“有效性”具有定义导航,并且当前未跟踪提供的实体。要开始跟踪此实体,请在所有者条目上调用“.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;
        }

    }

【问题讨论】:

  • 只需发布您如何获取实体以及如何更新它的代码

标签: asp.net-core ef-code-first


【解决方案1】:

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

在这一行之后: subscription.Validity = new Validity(startDate, endDate);

【讨论】:

    【解决方案2】:

    为了更新实体,实体必须对其进行跟踪,在下面的代码中,您正在创建新对象:

    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
                };
    

    首先你需要从db中获取那个实体,然后更新相关字段并保存到db;

    [更新]

    validity是一个与Subscription相关的实体,所以需要一个include查询从db中获取对象,然后更新保存。

    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();
    

    【讨论】:

    • 你能展示你的订阅和有效性的全班成员吗?据我所知,您有一个不同的有效性对象,对吧?
    • 好的,我正在更新已发布的问题
    • 已经发布的订阅类和有效性类(值对象)
    • 我使用了这个查询,但是发生了一些错误:CS1061 C# Subscription does not contain a definition for and no access extension method accept the first argument of type can be found(您是否缺少 using 指令或程序集参考?)
    • 好吧,很可能你的数据库中没有有效性表,我会更新答案
    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 2016-03-20
    • 2013-06-02
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    相关资源
    最近更新 更多