¿Hay una buena manera de aprovechar EdmFunctionAttribute
sin introducir una dependencia en The Entity Framework/System.Data.Entity.dll?¿Utiliza EdmFunctionAttribute sin exponer los detalles de dependencia/implementación de Entity Framework?
Pensé que podría tener una interfaz con un método y una implementación concreta que implemente el método usando EdmFunctionAttribute
para asignarlo a una función de base de datos.
Tengo una interfaz de contexto IMyContext
definida en un ensamblaje y una implementación de Entity Framework MyContext
en otro ensamblaje.
public interface IMyContext
{
double SomeFunction(double first, double second);
// other interface details here
}
public partial class MyContext : IMyContext
{
[EdmFunction("MyNamespace", "MyDatabaseFunction")]
public double SomeFunction(double first, double second)
{
throw new NotSupportedException("This method may only be called as part of a LINQ expression.");
}
// rest of interface implementation here
}
utilizo una fábrica (utilizando StructureMap detrás de las escenas) para obtener una instancia de contexto como el tipo de interfaz:
using (IMyContext context = ContextFactory.GetNewContext())
{
var results = context.Table.Select(t => context.SomeFunction(t.Col1, t.Col2)).ToList();
}
Esto arroja una NotSupportException
diciendo que LINQ a Entidades no reconoce el método ' Double SomeFunction (Double, Double) '.
Si yo echo el contexto de la aplicación concreta
using (MyContext context = ContextFactory.GetNewContext() as MyContext)
{
...
}
entonces funciona, pero luego se me requiere que especifique la aplicación concreta, que no quiero hacer.
La función no tiene que ser un miembro de la clase de contexto, simplemente la puse allí para explorar.
Me encuentro en la misma situación. Yo también esperaba que EdmFunctionAttribute se resolviera cuando se accede a través de una referencia de interfaz, pero fue en vano. Se vuelve aún más difícil cuando se trabaja con contextos múltiples (bases de datos múltiples). – kdawg
Por lo que vale, no pude resolver este problema y tuve que darle una bofetada a la función DB en la implementación concreta de mi Repositorio (Contexto en su caso), lo que significa que todas las llamadas a funciones deben residir dentro de mi clase de Repositorio, es decir: mi el código del cliente no pudo acceder a él directamente. No me entusiasma, pero funciona (y obliga a consultar el código a residir dentro del Repositorio, que algunos dirían que es donde pertenece). – kdawg