Лучший способ проверить, существует ли объект в Entity Framework?
каков наилучший способ проверить, существует ли объект в базе данных с точки зрения производительности? Я использую Entity Framework 1.0 (ASP.NET 3.5 SP1).
7 ответов:
Если вы не хотите выполнять SQL напрямую, лучший способ-использовать любой(). Это потому, что Any() вернется, как только найдет совпадение. Другой вариант:Count (), но это может потребоваться, чтобы проверить каждую строку перед возвращением.
вот пример того, как его использовать:
if (context.MyEntity.Any(o => o.Id == idToMatch)) { // Match! }
и в vb.net
If context.MyEntity.Any(function(o) o.Id = idToMatch) Then ' Match! End If
с точки зрения производительности, я думаю, что прямой SQL-запрос с помощью команда будет уместна. См. здесь, Как выполнить SQL непосредственно в Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity-framework-4.aspx
у меня были некоторые проблемы с этим - мой EntityKey состоит из трех свойств (PK с 3 столбцами), и я не хотел проверять каждый из столбцов, потому что это было бы некрасиво. Я думал о решении, которое работает все время со всеми сущностями.
еще одна причина для этого-я не люблю ловить UpdateExceptions каждый раз.
немного отражения необходимо, чтобы получить значения ключевых свойств.
код реализован как расширение упростите использование как:
context.EntityExists<MyEntityType>(item);
посмотреть:
public static bool EntityExists<T>(this ObjectContext context, T entity) where T : EntityObject { object value; var entityKeyValues = new List<KeyValuePair<string, object>>(); var objectSet = context.CreateObjectSet<T>().EntitySet; foreach (var member in objectSet.ElementType.KeyMembers) { var info = entity.GetType().GetProperty(member.Name); var tempValue = info.GetValue(entity, null); var pair = new KeyValuePair<string, object>(member.Name, tempValue); entityKeyValues.Add(pair); } var key = new EntityKey(objectSet.EntityContainer.Name + "." + objectSet.Name, entityKeyValues); if (context.TryGetObjectByKey(key, out value)) { return value != null; } return false; }
Мне пришлось управлять сценарием, в котором процент дубликатов, предоставляемых в новых записях данных, был очень высоким, и поэтому было сделано много тысяч вызовов базы данных для проверки дубликатов (поэтому процессор отправил много времени на 100%). В конце концов я решил сохранить в памяти последние 100 000 записей. Таким образом, я мог бы проверить наличие дубликатов в кэшированных записях, что было очень быстро по сравнению с запросом LINQ для базы данных SQL, а затем написать любой подлинно новые записи в базу данных (а также добавить их в кэш данных, который я также отсортировал и обрезал, чтобы сохранить его длину управляемой).
обратите внимание, что необработанные данные были CSV-файл, который содержал много отдельных записей, которые должны были быть проанализированы. Записи в каждом последующем файле (которые приходили со скоростью примерно 1 раз в 5 минут) значительно перекрывались, поэтому высокий процент дубликатов.
короче говоря, если у вас есть временные метки исходных данных, поступающих, в значительной степени в порядке, затем использование кэша памяти может помочь с проверкой дублирования записей.
Я знаю, что это очень старый поток, но просто упаковать кого-то, как я нуждается в этом решении, но в VB.NET вот что я использовал, основываясь на ответах выше.
Private Function ValidateUniquePayroll(PropertyToCheck As String) As Boolean // Return true if Username is Unique Dim rtnValue = False Dim context = New CPMModel.CPMEntities If (context.Employees.Any()) Then ' Check if there are "any" records in the Employee table Dim employee = From c In context.Employees Select c.PayrollNumber ' Select just the PayrollNumber column to work with For Each item As Object In employee ' Loop through each employee in the Employees entity If (item = PropertyToCheck) Then ' Check if PayrollNumber in current row matches PropertyToCheck // Found a match, throw exception and return False rtnValue = False Exit For Else // No matches, return True (Unique) rtnValue = True End If Next Else // The is currently no employees in the person entity so return True (Unqiue) rtnValue = True End If Return rtnValue End Function
Я просто проверяю, если объект null, он работает 100% для меня
try { var ID = Convert.ToInt32(Request.Params["ID"]); var Cert = (from cert in db.TblCompCertUploads where cert.CertID == ID select cert).FirstOrDefault(); if (Cert != null) { db.TblCompCertUploads.DeleteObject(Cert); db.SaveChanges(); ViewBag.Msg = "Deleted Successfully"; } else { ViewBag.Msg = "Not Found !!"; } } catch { ViewBag.Msg = "Something Went wrong"; }