通过实体框架保存显式实体

时间:2016-05-06 04:09:04

标签: entity-framework

让我们说我正在从Excel文件中读取数据,我需要使用EF保存它。在阅读excel之后,我在我的EF模型中构建了一个类型的实体 - 比如Holiday。

很可能这个特殊假期已存在于我的数据库中,或者可能不存在。我只是通过阅读Excel文件就无法了解它。所以,我检查该实体是否存在,如果存在,我必须修改现有实体或添加新实体。

以下是我处理逻辑的方式。

 foreach (var holiday in clientDataObj.Holidays)
 {
     // to check for existing holidays, no need to consider the location, as all holidays will anyway exist at root level.
     Holiday existingHoliday =
                ClientContext.Holidays.SingleOrDefault(h => string.Equals(h.Date, holiday.Date));

     if (existingHoliday == null)
     {
         rootLocation.Holidays.Add(holiday);
     }
     else
     {
         holiday.HolidayId = existingHoliday.HolidayId;
         ClientContext.Entry(existingHoliday).State = System.Data.Entity.EntityState.Detached;
         ClientContext.Entry(holiday).State = System.Data.Entity.EntityState.Modified;
     }
}

ClientContext.SaveChanges();

我还没有运行代码来查看它是否有效。有人可以知道这是否是这样做的方法,或者是否有其他最佳实践来解决这个问题。

1 个答案:

答案 0 :(得分:1)

不,那不行。分离实体不会将其删除,只是与上下文的跟踪分离。

您需要删除它并添加新的:

 <Grid Grid.Column="0" Background="Transparent" Tapped="DrawerIcon_Tapped" HorizontalAlignment="Center" VerticalAlignment="Center">
      <Image Margin="10" x:Name="DrawerIcon"  Source="/Assets/but_drawer.png" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center" VerticalAlignment="Center" >
          <Image.RenderTransform>
               <CompositeTransform ScaleX="0.5" ScaleY="0.5"/>
          </Image.RenderTransform>
     </Image>
 </Grid

此外,如果excel文件中有两个相同的假期,您可以通过已添加的假期,因此您需要检查该假期。在这里分离是有效的,因为你还没有调用ClientContext.Entry(existingHoliday).State = EntityState.Deleted; ClientContext.Entry(holiday).State = EntityState.Added; ,所以实体还没有在数据库中:

SaveChanges

我不确定为什么在数据库中不存在它们时将它们添加到if(ClientContext.Entry(existingHoliday).State == EntityState.Added) ClientContext.Entry(existingHoliday).State == EntityState.Detached; ,如果我遵循你的逻辑,你应该将它们添加到上下文中,这样你就可以有这个循环:

rootLocation

同样,我不确定foreach (var holiday in clientDataObj.Holidays) { Holiday existingHoliday = ClientContext.Holidays.SingleOrDefault(h => string.Equals(h.Date, holiday.Date)); if (existingHoliday != null) { holiday.Id = existingHoliday.Id; ClientContext.Entry(existingHoliday).State = ClientContext.Entry(existingHoliday).State == EntityState.Added ? EntityState.Detached : EntityState.Deleted; } ClientContext.Entry(holiday).State = System.Data.Entity.EntityState.Added; } 是什么,所以你的逻辑可能会有所不同。

作为进一步的优化,如果假期列表不是太大,你应该将它全部加载到内存中,而不是在每次迭代时都调用rootLocation,这将打到数据库。

所以只有一次点击数据库加载所有这些(再次,如果没有太多,内存不是问题),并在客户端搜索:

SingleOrDefault

这应该只对数据库进行一次查询

请注意,如果同时使用此方法和上述方法,则还需要将新假期添加到列表中,以便在excel导入可能重复时对其进行检查。这在您的问题中都是未指定的,因此请查看规格。