实体框架未跟踪列表

时间:2020-03-03 05:01:15

标签: asp.net asp.net-mvc entity-framework orm entity-framework-6

我将EF6与ASP.Net一起使用。我正在尝试在以下模型中将项目添加到“作业”列表中:

编辑:

我的目标是通过PUT方法保存对Timecards.Jobs列表所做的更改,以便可以通过GET方法检索它们。

public class Timecard
    {
        [Key]
        public long TimecardID { get; set; }
        [Required]
        public DateTime StartDate { get; set; }
        [Required]
        public DateTime EndDate { get; set; }
        [Required]
        public long EmployeesID { get; set; }
        [Required]
        public decimal Hours { get; set; }
        [Required]
        public  ICollection<int> Jobs { get; set; } = new List<int>();

        public List<DateTime> Days { get; set; } = new List<DateTime>();
    }

我相信我正在这样做,我正在检查PUT方法中的状态变化:


    // PUT: api/TimecardsAPI/5
            [ResponseType(typeof(void))]
            public IHttpActionResult PutTimecard(int id, Job job)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                try
                {                
                    Timecard card = db.Timecards.Where(x => x.TimecardID == id).First();
                    var state = db.Entry(card).State;                
                    db.Timecards.Attach(card);
                    state = db.Entry(card).State;
                    card.Jobs.Add((int)job.JobID);
                    db.Entry(card).State = EntityState.Modified;
                    state = db.Entry(card).State;
                    var result = db.SaveChanges();
                    state = db.Entry(card).State;
                    var change = db.Timecards.Where(x => x.TimecardID == id).First().Jobs;
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!TimecardExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return StatusCode(HttpStatusCode.NoContent);

            }

在从put方法返回之前,完成工作后,我需要进行var更改以检查Jobs列表的结果。在离开put方法之前,对Jobs列表所做的更改是准确的。但是,当我进行获取时,除了列表之外,我还获取了所有正确的数据。它以长度为0的列表形式返回。这是我的get方法,在变量中也有作业列表。这是列表以大小0返回的地方:

// GET: api/TimecardsAPI
        public IQueryable<Timecard> GetTimecards()
        {
            var change = db.Timecards.Where(x => x.TimecardID == 6).First().Jobs;
            //In this example, six is the id of the timecard in question. Only hardcoded here
            //for debugging.
            return db.Timecards;
        }

和我的dbcontext:



    public class ClockedWebContext : DbContext
        {   
            public ClockedWebContext() : base("name=ClockedWebContext")
            {
            }

            public DbSet<Job> Jobs { get; set; }

            public System.Data.Entity.DbSet<ClockedWeb.Models.PayPeriod> PayPeriods { get; set; }

            public System.Data.Entity.DbSet<ClockedWeb.Models.Employee> Employees { get; set; }

            public System.Data.Entity.DbSet<ClockedWeb.Models.Timecard> Timecards { get; set; }
}

关于SO有很多类似的问题,但是我还没有找到可以帮助我解决问题的信息。我不知道我在做什么错,但是我在这方面已经浪费了几天,我真的可以使用一些帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

通常在列中存储倍数值表明数据库设计不良。关系数据库是专门为每行/每列组合存储一个值而设计的。为了存储多个值,必须将列表序列化为单个值进行存储,然后在检索时反序列化它,或者可以使用多对一关系,然后应该使用带有外键约束的额外表。 RDMS中没有其他方法可以做到这一点。

如果您使用序列化方法,那么您的模型看起来就像-

    public class Timecard
    {
        [Key]
        public long TimecardID { get; set; }
        [Required]
        public DateTime StartDate { get; set; }
        [Required]
        public DateTime EndDate { get; set; }
        [Required]
        public long EmployeesID { get; set; }
        [Required]
        public decimal Hours { get; set; }        
        [NotMapped]
        public  List<int> JobList { get; set; } = new List<int>();
        [Required]
        public string Jobs
        {
            get => string.Join(",", JobList);
            set
            {
                if (string.IsNullOrEmpty(value)) JobList = new List<int>();
                else
                {
                    JobList = !string.IsNullOrWhiteSpace(value) && value.Contains(",")
                        ? value.Split(',').Select(s => Convert.ToInt32(s.Trim())).ToList()
                        : !string.IsNullOrWhiteSpace(value) && !value.Contains(",")
                            ? new List<int>()
                            : new List<int>();
                }
            }
        }
        //have to change also
        public List<DateTime> Days { get; set; } = new List<DateTime>();//Follow previous technique
    }

然后,您可以在进行操作时进行操作。只是将数据插入为逗号分隔的字符串。

答案 1 :(得分:0)

我没有正确地获得您的信息,但是如果您在更改实体后仍未获得更新,那么可以在下面添加行

db.savechanges();
相关问题