Лучший способ проверить, существует ли объект в Entity Framework?


каков наилучший способ проверить, существует ли объект в базе данных с точки зрения производительности? Я использую Entity Framework 1.0 (ASP.NET 3.5 SP1).

7 92

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";
    }

почему бы и нет?

var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();

if(result.field == value)
{
  // Match!
}