Kelly VM
Kelly VM

Reputation: 45

Entity Framework not tracking List

I'm using EF6 with ASP.Net. I'm trying to add items to the Jobs list in the following model:

EDIT:

My goal is to save the changes I make to the Timecards.Jobs list through a PUT method in such a way that I can retrieve them through a GET method.

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

And I believe i'm doing so, i'm checking the states change in my PUT method:


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

            }

Before returning from the put method, i have a var change to check the results of the Jobs list once i'm done working on it. Before I leave the put method, the changes to the Jobs list are accurate. However, when I do a get, I get all the correct data EXCEPT the list. It comes back as a 0 length list. Here's my get method, which also has the jobs list in a variable. This is where the list comes back as size 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;
        }

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

There are many similar questions on SO but I have not found information yet that has helped me solve my issue. I have no idea what I'm doing wrong, but I've lost days on this and I could really use some help. thank you.

Upvotes: 1

Views: 259

Answers (2)

Ashiquzzaman
Ashiquzzaman

Reputation: 5284

Generally storing multiples values in column is an indication of poor database design. Relational databases are designed specifically to store one value per row/column combination. In order to store more than one value, you must serialize your list into a single value for storage, then deserialize it upon retrieval or you can use many-to-one relationship then you should use an extra table with a foreign key constraint. There is no other way to do so in RDMS.

If you use serialize approach, then your model look like--

    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
    }

Then you can do your operation as you doing. just it's insert data as a coma separated string.

Upvotes: 1

Karan Ekkawala
Karan Ekkawala

Reputation: 327

I am not getting you correctly but if you not getting the update after you changed your entity then can you please add below line

db.savechanges();

Upvotes: 0

Related Questions