Entity Framework 未跟踪列表
Entity Framework not tracking List
我在 ASP.Net 中使用 EF6。我正在尝试将项目添加到以下模型的工作列表中:
编辑:
我的目标是通过 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 列表的更改是准确的。但是,当我执行 get 时,我得到了除列表之外的所有正确数据。它作为 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;
}
和我的数据库上下文:
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 上有很多类似的问题,但我还没有找到可以帮助我解决问题的信息。我不知道我做错了什么,但我已经为此浪费了几天时间,我真的需要一些帮助。谢谢。
我没有正确理解你的意思,但如果你在更改实体后没有收到更新,那么你可以在下面添加行
db.savechanges();
通常在列中存储多个值表明数据库设计不佳。关系数据库专门设计用于为每个 row/column 组合存储一个值。为了存储多个值,您必须将列表序列化为单个值进行存储,然后在检索时反序列化它,或者您可以使用多对一关系,那么您应该使用一个额外的 table 和一个外部关键约束。在 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
}
然后你就可以按照你的操作来操作了。只是将数据作为逗号分隔的字符串插入。
我在 ASP.Net 中使用 EF6。我正在尝试将项目添加到以下模型的工作列表中:
编辑:
我的目标是通过 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 列表的更改是准确的。但是,当我执行 get 时,我得到了除列表之外的所有正确数据。它作为 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;
}
和我的数据库上下文:
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 上有很多类似的问题,但我还没有找到可以帮助我解决问题的信息。我不知道我做错了什么,但我已经为此浪费了几天时间,我真的需要一些帮助。谢谢。
我没有正确理解你的意思,但如果你在更改实体后没有收到更新,那么你可以在下面添加行
db.savechanges();
通常在列中存储多个值表明数据库设计不佳。关系数据库专门设计用于为每个 row/column 组合存储一个值。为了存储多个值,您必须将列表序列化为单个值进行存储,然后在检索时反序列化它,或者您可以使用多对一关系,那么您应该使用一个额外的 table 和一个外部关键约束。在 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
}
然后你就可以按照你的操作来操作了。只是将数据作为逗号分隔的字符串插入。