Entity Framework не отслеживает список - PullRequest
1 голос
/ 03 марта 2020

Я использую EF6 с ASP. Net. Я пытаюсь добавить элементы в список заданий в следующей модели:

РЕДАКТИРОВАТЬ:

Моя цель - сохранить изменения, внесенные в список Timecards.Jobs, с помощью метода PUT в таким образом, что я могу получить их с помощью метода 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, чтобы проверить результаты списка заданий, как только я закончу работать над ним. Прежде чем я оставлю метод put, изменения в списке заданий являются точными. Тем не менее, когда я получаю, я получаю все правильные данные за исключением списка. Это возвращается как список длины 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 ]

1 голос
/ 03 марта 2020

Как правило, хранение кратных значений в столбце указывает на плохую структуру базы данных. Реляционные базы данных предназначены специально для хранения одного значения на комбинацию строки / столбца. Чтобы сохранить более одного значения, вы должны сериализовать свой список в одно значение для хранения, а затем десериализовать его при извлечении, или вы можете использовать отношение многие-к-одному, тогда вам следует использовать дополнительную таблицу с ограничением внешнего ключа. В 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
    }

Тогда вы сможете выполнять свою работу так же, как и вы. просто это вставка данных в виде строки, разделенной запятой.

0 голосов
/ 03 марта 2020

Я не получаю вас правильно, но если вы не получаете обновление после того, как изменили свою сущность, то можете ли вы добавить ниже строку

db.savechanges();
...