Pregunta

¿Cuál es la mejor manera de verificar si un objeto existe en la base de datos desde un punto de vista de rendimiento? Estoy usando Entity Framework 1.0 (ASP.NET 3.5 SP1).

¿Fue útil?

Solución

Si no desea ejecutar SQL directamente, la mejor manera es usar Cualquier () . Esto se debe a que Any () regresará tan pronto como encuentre una coincidencia. Otra opción es Count () , pero es posible que tenga que revisar cada fila antes de regresar.

Aquí hay un ejemplo de cómo usarlo:

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

Y en vb.net

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

Otros consejos

Desde el punto de vista del rendimiento, supongo que una consulta SQL directa utilizando El comando EXISTS sería apropiado. Consulte aquí para saber cómo ejecutar SQL directamente en Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity -framework-4.aspx

Tuve que administrar un escenario en el que el porcentaje de duplicados que se proporcionaron en los nuevos registros de datos fue muy alto, y se hicieron muchas miles de llamadas a la base de datos para verificar si hay duplicados (por lo que la CPU envió mucho tiempo a 100 %). Al final decidí guardar los últimos 100,000 registros en la memoria caché. De esta manera, pude verificar si había duplicados en los registros almacenados en caché, lo cual fue extremadamente rápido en comparación con una consulta LINQ contra la base de datos SQL, y luego escribir registros genuinamente nuevos en la base de datos (así como agregarlos a la caché de datos, que también ordenados y recortados para mantener su longitud manejable).

Tenga en cuenta que los datos sin procesar eran un archivo CSV que contenía muchos registros individuales que debían analizarse. Los registros en cada archivo consecutivo (que se produjo a una tasa de aproximadamente 1 cada 5 minutos) se superponían considerablemente, de ahí el alto porcentaje de duplicados.

En resumen, si está ingresando los datos sin procesar con marca de tiempo, bastante en orden, entonces usar un caché de memoria podría ayudar con la verificación de la duplicación de registros.

Sé que este es un tema muy antiguo, pero en caso de que alguien como yo necesite esta solución, pero en VB.NET esto es lo que usé en base a las respuestas anteriores.

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

Tuve algunos problemas con esto: mi EntityKey consta de tres propiedades (PK con 3 columnas) y no quería comprobar cada una de las columnas porque eso sería feo. Pensé en una solución que funcione todo el tiempo con todas las entidades.

Otra razón para esto es que no me gusta capturar UpdateExceptions todas las veces.

Se necesita un poco de Reflexión para obtener los valores de las propiedades clave.

El código se implementa como una extensión para simplificar el uso como:

context.EntityExists<MyEntityType>(item);

Echa un vistazo:

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

Acabo de comprobar si el objeto es nulo, funciona al 100% para mí

    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 qué no hacerlo?

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

if(result?.field == value)
{
  // Match!
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top