Pregunta

Soy nuevo en el marco de la entidad y tengo problemas con algo que fue bastante fácil en T-SQL puro. Suponga que tenemos tabla con 3 columnas. Id (identidad, clave primaria), idkind (int), número (int). Columna Nubmer depende de la columna IDKind. Los datos en esta tabla deberían verse así:

ID | IDKIND | Número

1 | 1 | 1

2 | 1 | 2

3 | 1 | 3

4 | 2 | 1

5 | 2 | 2

6 | 2 | 3

Como puede ver, el número de columna se incrementa automáticamente depende de IDKind. En T-SQL estaba encontrando Max (número) + 1 para algún IDKind. Todo estaba en un procedimiento almacenado en una transacción, por lo que el valor del número era único para IDKind.

Cómo lograr lo mismo en el marco de entidad. El valor del número debe calcularse al crear un nuevo objeto o al cambiar IDKind.

¿Fue útil?

Solución

Usaría el activador de la base de datos para eso y configuraría Number Propiedad en Mapeo de EF con StoreGeneratedPattern.Computed Para informar a EF que esta propiedad se llena en la base de datos y debe volver a cargarse después de cada actualización / inserción.

Tampoco usaría max () para cada nuevo número. En cambio, mantendría secuencias de simulación de tabla separadas. Esta tabla debe contener registro por secuencia, en su caso de registro por IdKind con el número máximo actual. En lugar de seleccionar la agregación, seleccionará un registro único y lo actualizará para contener un nuevo número máximo. Trabajar con esta tabla debe estar en la misma transacción que cambios persistentes en su entidad.

Otros consejos

Tuve el mismo problema pero lo resolví en C#.

Debería tener una entidad mapeada en la mesa:

public class MyEntity
{ 
     Kind IdKind{get; set;}
     int Number{get;set;}
}

Debería tener una entidad auxiliar para almacenar el último número utilizado por tipo.

public class LastNumber
{ 
     Kind IdKind{get;set;}
     int LastNumber{get;set;}
}

Luego, antes de agregar una fila (objeto MyEntity) a la tabla, debo calcular el número adecuado utilizando el campo de último número de inicio de número de número iguales con el valor de mi tipo.

Debemos tener en cuenta que esta estrategia tiene un problema de concurrencia porque dos hilos diferentes podrían agregar un objeto del mismo tipo al mismo tiempo, esos hilos inspeccionarán la misma cantidad de inicio para obtener el valor de último número. Este problema tiene una solución conocida en EntityFramework. El código podría verse así:

 public int GetNumber(Kind idKind)
    {
        using (var db = new MyDataContext())
        {
            var lastNumber = db.LastNumbers.Single(x=>x.IdKind == idKind);
            for (int attemps = 0; attemps < 10;)
            {
                try
                {
                    lastNumber.LastNumber++;
                    db.SaveChanges();
                    return lastNumber.LastNumber;
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    attemps++;
                }
            }
        }

        throw new Exception("Many concurrency calls");
    }

Este método obtiene un número incremental para un tipo especificado y maneja el problema de concurrencia, utilizándolo, podemos establecer el valor de número para cada objeto MyEntity. El código del cliente podría verse así:

var entity = new MyEntity();
var number = GetNumber(entity.IdKind);
entity.Number = number;
db.MyEntities.Add(entity);
db.SaveChanges();

Este código podría refactorizarse, haciendo que los establecedores sean privados, haciendo una fábrica para garantizar que las entidades siempre se creen utilizando el método GetNumber y utilizando repositorios para administrar el DB.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top