2013-10-24 72 views
3

我正在写一个爬网程序,应该去一个网站,从那里提取一些数据,然后将其存储到一个数据库中,事情是爬虫应该也更新已经在以前运行中找到的数据。在EF中插入/更新实体?

ParseDataPage返回在EF POCO中从站点解析的信息,它的一个属性是唯一标识符(它也是db表中的主键),如何告知EF插入/添加对象?

class Program 
{ 
    static void Main() 
    { 

     var context = (adCreatorEntities) DbContextFactory.GetInstance().GetDbContext<adCreatorEntities>(); 
     var crawler = new DataCrawler();    
     crawler.Login(); 
     var propertyIds = crawler.GetPropertyIds(); 

     foreach (var id in propertyIds) 
     { 
      var poco = crawler.ParseDataPage(id); 
      context.Properties.Add(poco); //<-- How can I tell EF to update if the record exists or to insert it otherwise?? 
      context.SaveChanges(); 
     } 

     context.SaveChanges(); 

     if (crawler.LoggedIn) 
      crawler.Logout(); 
    } 
} 

回答

4

您可以将实体状态设置为Modified或实体添加到基于关键字的值DbSet

if(entity.propertyId <= 0) 
{ 
    context.Properties.Add(poco); 
} 
else 
{ 
     context.Entry(poco).State = EntityState.Modified; 
} 

这是EF5代码,EF4是用于设置对象状态

context.ObjectStateManager.ChangeObjectState(poco, EntityState.Modified); 
+0

我还是不要没办法。我的意思是,在我调用'var poco = parseDataPage(id)'后,将始终设置poco.Id。无论是新纪录还是现有纪录。所以我应该总是做'var poco = parseDataPage(id); poco.State = EntityState.Modified; context.Properties.Attach(POCO);'?? –

+0

我的代码假定一个新的poco不会有一个id为<= 0的。我建议'parseDataPage'不要在它是一个新对象的情况下设置ID,否则,除了其他问题之外,您必须进行额外的调用以检查是否存在。 – Shoe

1

略有不同,您可以检查记录是否存在使用下面的代码,

var entity= dataContext.Properties.Find(b => b.UniqueId == poco.UniqueId); 
        if (entity== null) 
        { 
         dataContext.Properties.Add(poco); 
        } 
        else 
        { 
         dataContext.Entry(entity).State = EntityState.Modified; 
        } 
        dataContext.SaveChanges();