实体框架从List重新启动后丢失数据

时间:2015-03-10 19:52:39

标签: c# sql-server asp.net-mvc entity-framework asp.net-mvc-4

我在使用实体框架为数据库编写C#ASP的网站存在问题。我用来存储和检索名为DowntimeEvent的数据的数据模型之一包含2个列表AffectedSystems和AffectedDepartments。当我在Visual Studio中运行应用程序时,这些列表存储和检索就好了。但是,如果我停止并重新启动应用程序,则DowntimeEvents仍存储在我的数据库中,但是当我尝试检索它们时,受影响部门和受影响系统的列表为空。

这是模型I用来存储数据

public class DowntimeEventModel
{
    [Key]
    public int ID { get; set; }
    [Required]
    public DateTime StartDateTime { get; set; }
    [Required]
    public DateTime EndDateTime { get; set; }
    public int LocationID { get; set; }
    [Required]
    public string Description { get; set; }
    //public int DepartmentID { get; set; }
    //public int SystemID { get; set; }
    public virtual ICollection<int> AffectedSystems { get; set; }
    public virtual ICollection<int> AffectedDepartments { get; set; }
    //public virtual ICollection<SystemModel> AffectedSystems { get; set; }
    //public virtual ICollection<DepartmentModel> AffectedDepartments { get; set; }
}

以下是我如何保存数据的控制器示例,以及在存储列表时这似乎正常工作的方式。

[HttpPost]
    public ActionResult DowntimeEvent(DowntimeEventModel downtimeEvent)
    {
        PowerteqContext.DowntimeEvents.Add(downtimeEvent);
        PowerteqContext.SaveChanges();
        return View(SetupDowntimeEventViewModel());
    }

在尝试编写此报告并尝试找出为什么AffectedSystems有时为空(有时不是)时,正是这种方法让我想到了数据检索的问题。在内部foreach循环中,我试图直接访问ListAffectedSystems只是为了查看循环可能不是那样的,并且是在重新启动之后,但是如果我添加它们并且不重新启动则不行。

        public ActionResult ReportUptimeBySystems()
    {

        var EndTime = DateTime.Now;
        var StartTime = DateTime.Now.AddDays(-28);
        var uptimeHours = new TimeSpan(1);
        if (EndTime != StartTime)
            uptimeHours = EndTime - StartTime;

        List<ReportUptimeBySystem> SysUps = new List<ReportUptimeBySystem>();
        var DownTimes = PowerteqContext.DowntimeEvents.AsEnumerable();
        var Systems = PowerteqContext.Systems.AsEnumerable();

        foreach (var x in Systems)
        {
            ReportUptimeBySystem sys = new ReportUptimeBySystem();
            sys.SystemTimeUP = uptimeHours;
            sys.SystemName = x.SystemName;
            foreach (var y in DownTimes)
            {
                if(PowerteqContext.DowntimeEvents.Find(y.ID).AffectedSystems.Contains(x.ID))
                {
                    sys.SystemTimeUP -= y.StartDateTime - y.EndDateTime;
                }
            }
            SysUps.Add(sys);
        }
        return View(SysUps);
    }

另一位开发人员建议问题可能出在我的实体框架配置中。但我不知道在哪里寻找甚至试图解决这个问题。

供参考,可在此处找到整个申请表。我使用的数据库是Microsoft SQL Server here

2 个答案:

答案 0 :(得分:1)

实体框架只有在找到表示另一个实体的集合的属性时才会自动加载关系。它还必须能够识别外键。根据标准,SystemModel和DepartmentModel应具有属性DowntimeEventID,否则您必须告知它如何为您执行此操作。

您还应该确保不会禁用延迟加载。

https://msdn.microsoft.com/en-us/data/jj574232.aspx

Disable lazy loading by default in Entity Framework 4

以下是相关问题的一个很好的例子。 Many-to-many mapping table

public class DowntimeEventModel
{
    [Key]
    public int ID { get; set; }
    [Required]
    public DateTime StartDateTime { get; set; }
    [Required]
    public DateTime EndDateTime { get; set; }
    public int LocationID { get; set; }
    [Required]
    public string Description { get; set; }
    public virtual ICollection<SystemModel> AffectedSystems { get; set; }
    public virtual ICollection<DepartmentModel> AffectedDepartments { get; set; }
}

答案 1 :(得分:0)

假设AffectedSystemsAffectedDepartments也是DowntimeEventModel与外键关联的EF实体,您可以尝试在获取DowntimeEventModel结果时明确包含它们就这样:

PowerteqContext.DowntimeEventModel.Include("DowntimeEventModel.AffectedSystems").Include("DowntimeEventModel.AffectedDepartments").ToList();