2012-02-15 112 views
9

我第一次使用Ado.net實體框架,並且在將其插入數據庫之前需要檢查此記錄是否存在。最好我會搜索是否存在AuthodSSID而不是密鑰(AuthorID)。我使用的是VS2010,Framework 4,System.Data.Entity是3.5.0.0。在插入新記錄之前檢查記錄的存在

我使用Google搜索,但沒有找到這個問題的答案。

PublishingCompanyEntities publishContext; 
publishContext = new PublishingCompanyEntities(); 

private void createNew_Click(object sender, EventArgs e) 
{ 
    Author newAuthor = new Author(); 
    newAuthor.FirstName = firstName.Text; 
    newAuthor.LastName = lastName.Text; 
    newAuthor.AuthodSSID = 20; 
    newAuthor.AuthorID = 10 
//Check if record exist here 
    publishContext.AddToAuthor(newAuthor);//insert if does not exist 

} 
+1

舊的但仍然看起來像一個DUP;更多信息可以在http://stackoverflow.com/questions/1802286/best-way-to-check-if-object-exists-in-entity-framework – Nenotlep 2013-04-25 06:47:46

+0

找到[最好的方法來檢查對象是否存在實體框架?](https://stackoverflow.com/questions/1802286/best-way-to-check-if-object-exists-in-entity-framework) – 2017-12-26 14:00:18

回答

14

來檢查記錄是否存在的唯一方法是要查詢的記錄,看看是否有任何回來:

var existingAuthorCount = publishContext.Author.Count(a => a.AuthodSSID == 20); 
if (existingAuthorCount == 0) 
{ 
    // Do your insert 
} 
+1

工作,只需要弄清楚.Count爲什麼沒有出現。簡單, 使用System.Linq;在頂部失蹤! TKX! – BirdOfPrey 2012-02-15 03:45:41

+0

從臭名昭着的埃裏克利珀特的明智建議:你有一個完全滿滿的便士罐子。有人問你「那個罐子裏有沒有便士?」。 **你計算它們,然後比較答案爲零,或者你是否在罐子裏至少有一分錢?**([Citation](http://stackoverflow.com/questions/9194908/safely-檢查,不可重複,ienumerables換空虛#comment11574518_9194908))。此解決方案的性能取決於'Author'中包含的行數。我已經更新了我的答案,將結果查詢限制爲僅查找1. – 2012-02-15 04:15:16

+4

您是否可以不使用publishContext.Author.Any(a => a.AuthodSSID == 20)或者.Any()在EF中不可用? – 2012-10-29 21:29:59

12

像這樣的東西應該工作:基於

if (publishContext.Author.Select(a => a.AuthodSSID).Where(id => id == 20).Take(1) == null) 
    // It doesn't exist 
else 
    // It does exist 

我的(雖然基本)理解這應該產生一個SQL語句相當於:

SELECT TOP(1) AutodSSID FROM Author WHERE AuthodSSID = 20; 

另一種更簡單的方法可能會使用Any擴展方法:

if (!publishContext.Author.Any(a => a.AuthodSSID == 20)) 
    // Put your insert logic here. 
+0

這將工作,最好是如果你想更新作者如果它確實存在。但是,這將爲作者選擇所有列,而這些列可能不需要。按照我的答案進行計數會更有效率。 – Jacob 2012-02-15 03:32:15

+0

@Jacob - 計數實際上與包括選擇單個列相同,但使用SingleOrDefault,我認爲它會做'TOP 1',其中'COUNT(*)'仍然需要* all * of記錄,還是我錯過了什麼? – 2012-02-15 03:42:09

+1

好問題。我對'TOP 1'的關注是所有*列*仍然返回那一行。 「COUNT」可能需要在數據庫上進行更多的表掃描,但只返回一個整數。也許最好的選擇是做一個'Where',然後是'Select'主鍵,然後是'Take(1)'。這應該解決這兩個問題。 – Jacob 2012-02-15 05:07:13

0

所有您需要做的就是搜索(使用linq)具有該ID的作者。

Where()方法將返回您只需要一個作者的集合,因此您使用返回第一個元素的FirstOrDefault(),如果沒有任何內容,則返回null。您也可以使用SinglOrDefault,如果列表中有多個元素或者僅返回該元素,則會引發異常。

看起來@Jacob有一個很好的,更高效的方法!

var author = publishContext.Authors.Where 
           (a=>a.AuthodSSID == 10).FirstOrDefault(); 
if(author == null) //none exist 
{//don't bother creating one unless you need to.. 
    Author newAuthor = new Author(); 
    newAuthor.FirstName = firstName.Text; 
    newAuthor.LastName = lastName.Text; 
    newAuthor.AuthodSSID = 20; 
    newAuthor.AuthorID = 10 
    publishContext.AddToAuthor(newAuthor);//insert if does not exist 
} 
2

我個人更喜歡從一個.NET點這種方法。它更乾淨,如果你關心速度(在.NET中),它更高效,但是SQL不是那種閃存;

private bool CheckIfEntityRecordExists(Entity e) 
{ 
    var retVal = false; 
    using (var db = new EntityContext()) 
    { 
     retVal = db.AdviserClients.Any(a => a.Id == e.Id); 
    } 
    return retVal; 
} 

所以對於一個有效的SQL語句,下面的纔是最好的:

private bool CheckIfEntityRecordExists(Entity e) 
{ 
    var retVal = false; 
    using (var db = new EntityContext()) 
    { 
     retVal = db.AdviserClients.Count(a => a.Id == e.Id) > 0; 
    } 
    return retVal; 
} 
+1

儘管我已經upvoted你的答案,但從性能的角度來看,應該使用db.context.Any()作爲db.contex.count()將迭代所有數據,而.Any只會在第一場比賽停止。 – 2015-04-28 13:40:31

0

還有就是所謂的 「更新插入」 操作EF V5.0 +

publishContext.Author.AddOrUpdate(x => x.Id, newAuthor) 

AddOrUpdate可用可以在「System.Data.Entity.Migrations」命名空間中找到,所以不要忘記添加:

using System.Data.Entity.Migrations; 

AddOrUpdate操作不是原子的。但是* if(existingAuthorCount == 0){//做你的插入}也不是。

相關問題