Pergunta

O que é a melhor maneira de verificar se um objeto existe no banco de dados a partir de um ponto de vista do desempenho? Estou usando Entity Framework 1.0 (ASP.NET 3.5 SP1).

Foi útil?

Solução

Se você não quiser executar SQL diretamente, a melhor maneira é usar Any () . Isso ocorre porque Any () irá retornar assim que encontra uma correspondência. Outra opção é Count () , mas esta necessidade poder verificar cada linha antes de retornar.

Aqui está um exemplo de como usá-lo:

if (context.MyEntity.Any(o => o.Id == idToMatch))
{
    // Match!
}

E em vb.net

If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
    ' Match!
End If

Outras dicas

Do ponto de vista do desempenho, eu acho que uma consulta SQL direta usando o EXISTE comando seria apropriado. Veja aqui como executar SQL diretamente no Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity -framework-4.aspx

I teve de gerir um cenário em que a percentagem de duplicatas a ser fornecido nos novos registros de dados foi muito alto, e tantos milhares de chamadas de banco de dados estavam sendo feitos para verificar se há duplicatas (para que a CPU enviou um monte de tempo a 100 %). No final, eu decidi manter os últimos 100.000 registros em cache na memória. Desta forma, eu poderia verificar se há duplicatas contra os registros armazenados em cache que foi extremamente rápido quando comparado a uma consulta LINQ contra o banco de dados SQL, e em seguida, escrever qualquer genuinamente novos registros para o banco de dados (bem como adicioná-los para o cache de dados, que eu também ordenada e aparadas para manter a sua gerenciável comprimento).

Note que os dados brutos era um arquivo CSV que continha muitos registros individuais que tiveram que ser analisado. Os registros em cada arquivo consecutivo (que veio a uma taxa de cerca de 1 a cada 5 minutos) sobreposta consideravelmente, daí o alto percentual de duplicatas.

Em suma, se você tiver timestamped dados brutos que chegam, praticamente em ordem, em seguida, usando uma força de ajuda de memória cache com a verificação de registro duplicação.

Eu sei que este é um segmento muito antiga, mas alguém só meter como eu precisa dessa solução, mas em VB.NET aqui está o que eu usei base sobre as respostas acima.

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

Eu tive alguns problemas com isso - meu EntityKey consiste em três propriedades (PK com 3 colunas) e eu não queria verificar cada uma das colunas, porque isso seria feio. Eu pensei em uma solução que funciona todos os tempos com todas as entidades.

Outra razão para isso é que eu não gosto de UpdateExceptions captura de cada vez.

É necessário um pouco de reflexão para obter os valores das propriedades fundamentais.

O código é implementado como uma extensão para simplificar o uso como:

context.EntityExists<MyEntityType>(item);

Dê uma olhada:

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

Eu apenas verificar se o objeto é nulo, ele funciona 100% para mim

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

Por que não fazê-lo?

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

if(result?.field == value)
{
  // Match!
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top