¿Cómo puedo usar un método personalizado en una cláusula de selección de LINQ-to-SQL?

c# expression-trees linq-to-sql

Pregunta

Me gustaría hacer algo como lo que se describe en este artículo . Sin embargo, el artículo es de 2006 y requiere métodos de extensión que escribió el autor. Espero que haya algo más incorporado en este punto.

La intención aquí es guardar un método que contenga solo las operaciones traducibles a T-SQL y usarlo para asignar propiedades específicas en una declaración de selección de LINQ-to-SQL. Si hay una forma radicalmente diferente de hacer esto, entonces lo que he intentado, también es una respuesta válida.

¿Cómo lo hago?


Lo que he intentado

Tengo una consulta de este tipo:

var theData = (
    from inv in dc.Inventory
    where inv.IsDeleted == false
    join data in cdc.InventoryDatas
    on inv.InvKey equals data.ReInvKey
    where data.ReColKey == colKey
    select new MyClass {
        SerialNumber = inv.SerialNumber,
        Data = InventoryData.DataExpression( data ),
        Name = inv.Name,
    }
);

Donde InventoryData.DataExpression se define como tal:

public static Expression<Func<InventoryData, string>> DataExpression = (
    d => d.TextData != null ? d.TextData 
        : d.IntegerData != null ? d.IntegerData.ToString() 
        : d.DecimalData != null ? d.DecimalData.ToString() 
        : d.DateData != null ? d.DateData.ToString() 
        : d.BooleanData != null ? d.BooleanData.ToString()
        : null
);

Pero no está del todo bien. ¿Cómo puedo hacer que esto funcione?

Respuesta popular

Esto funciona bien cuando selecciono solo datos de una tabla, y cuando no combino otras expresiones en el lado derecho de la declaración de asignación para la misma propiedad:

Data = InventoryData.DataExpression.Compile()( data )

al igual que

select InventoryData.CompiledDataExpression( data )

y

select data.GetData()

donde CompiledDataExpression se define como

public static Func<InventoryData, string> CompiledDataExpression 
    = InventoryData.DataExpression.Compile();

y GetData se define como

public string GetData() {
    // execute the compiled delegete on this InventoryData
    var ret = InventoryData.CompiledDataExpression( this );

    return ret;
}

Sin embargo, el delegado no está realmente compilado para T-SQL. En su lugar, se extraen objetos completos del tipo asociado con la tabla, y luego el delegado se ejecuta sobre ellos localmente.

Recibo un error cuando intento la consulta completa, que se une a otras tablas y asigna al delegado a solo una de varias propiedades, algunas de las cuales extraen datos de las otras tablas.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow