微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 实体框架6更新图

保存状态不清楚的对象图形的正确方法是什么?按状态,我的意思是说它们是新的还是现在的数据库条目正在被更新.

例如,如果我有

public class Person
{
     public int Id { get; set; }
     public int Name { get; set; }
     public virtual ICollection<Automobile> Automobiles { get; set; }

}

public class Automobile
{
     public int Id { get; set; }
     public int Name { get; set; }
     public short Seats { get; set; }
     public virtual ICollection<MaintenanceRecord> MaintenanceRecords { get; set ;}
     public virtual Person Person { get; set; }
}

public class MaintenanceRecord
{
     public int Id { get; set; }
     public int AutomobileId { get; set; }
     public DateTime DatePerformed { get; set; }

     public virtual Automobile Automobile{ get; set; }

}

我正在编辑模型,类似于上述这些对象,然后将这些模型传递到数据层以保存,在这种情况下,我恰好是使用实体框架.所以我把这些模型翻译成DAL内部的POCO实体.

看来,除非我的模型有一个状态,指示它们是新的还是更新的,所以我有相当多的工作来“保存”更改.我必须首先选择Person实体,更新它,然后匹配任何现有的汽车,并更新那些并添加任何新的,然后为每个汽车检查任何新的或更新的维护记录.

有更快/更容易的方法吗?有可能我可以跟踪模型状态,我认为这对我有帮助,但这意味着我更愿意避免的数据层之外的代码的更改.我只是希望有一种使用方式,我可以按照这样的更新.

解决方法

我遇到这个问题一回,并在EF Codeplex网站上关注这个线程. https://entityframework.codeplex.com/workitem/864

似乎正在考虑下一个版本,我假设EF 7,这显然是一个非常大的EF内部大修.这可能值得一试… http://www.nuget.org/packages/RefactorThis.GraphDiff/

回来当我在这个工作时,我发现了另一个EF在SO上的帖子,有人举例说明如何手动这样做.当时我决定手动做,不知道为什么,GraphDiff看起来很酷.这是我做的一个例子.

public async Task<IHttpActionResult> PutAsync([FromBody] WellEntityModel model)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var kne = TheContext.Companies.First();
            var entity = TheModelFactory.Create(model);
            entity.DateUpdated = DateTime.Now;

            var currentWell = TheContext.Wells.Find(model.Id);

            // Update scalar/complex properties of parent
            TheContext.Entry(currentWell).CurrentValues.SetValues(entity);

            //We don't pass back the company so need to attached the associated company... this is done after mapping the values to ensure its not null.
            currentWell.Company = kne;

            // Updated geometry - ARGHHH NOOOOOO check on this once in a while for a fix from EF-Team https://entityframework.codeplex.com/workitem/864
            var geometryItemsInDb = currentWell.Geometries.ToList();
            foreach (var geometryInDb in geometryItemsInDb)
            {
                // Is the geometry item still there?
                var geometry = entity.Geometries.SingleOrDefault(i => i.Id == geometryInDb.Id);
                if (geometry != null)
                    // Yes: Update scalar/complex properties of child
                    TheContext.Entry(geometryInDb).CurrentValues.SetValues(geometry);
                else
                    // No: Delete it
                    TheContext.WellGeometryItems.Remove(geometryInDb);
            }
            foreach (var geometry in entity.Geometries)
            {
                // Is the child NOT in DB?
                if (geometryItemsInDb.All(i => i.Id != geometry.Id))
                    // Yes: Add it as a new child
                    currentWell.Geometries.Add(geometry);
            }

            // Update Surveys
            var surveyPointsInDb = currentWell.SurveyPoints.ToList();
            foreach (var surveyInDb in surveyPointsInDb)
            {
                // Is the geometry item still there?
                var survey = entity.SurveyPoints.SingleOrDefault(i => i.Id == surveyInDb.Id);
                if (survey != null)
                    // Yes: Update scalar/complex properties of child
                    TheContext.Entry(surveyInDb).CurrentValues.SetValues(survey);
                else
                    // No: Delete it
                    TheContext.WellSurveyPoints.Remove(surveyInDb);
            }
            foreach (var survey in entity.SurveyPoints)
            {
                // Is the child NOT in DB?
                if (surveyPointsInDb.All(i => i.Id != survey.Id))
                    // Yes: Add it as a new child
                    currentWell.SurveyPoints.Add(survey);
            }

            // Update Temperatures - THIS IS A HUGE PAIN = HOPE EF is updated to handle updating disconnected graphs.
            var temperaturesInDb = currentWell.Temperatures.ToList();
            foreach (var tempInDb in temperaturesInDb)
            {
                // Is the geometry item still there?
                var temperature = entity.Temperatures.SingleOrDefault(i => i.Id == tempInDb.Id);
                if (temperature != null)
                    // Yes: Update scalar/complex properties of child
                    TheContext.Entry(tempInDb).CurrentValues.SetValues(temperature);
                else
                    // No: Delete it
                    TheContext.WellTemperaturePoints.Remove(tempInDb);
            }
            foreach (var temps in entity.Temperatures)
            {
                // Is the child NOT in DB?
                if (surveyPointsInDb.All(i => i.Id != temps.Id))
                    // Yes: Add it as a new child
                    currentWell.Temperatures.Add(temps);
            }
            await TheContext.SaveChangesAsync();
            return Ok(model);
        }
        catch (Exception ex)
        {
            Trace.WriteLine(ex.Message);
        }
        return InternalServerError();
    }

原文地址:https://www.jb51.cc/csharp/96870.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐