Entity Framework en un Azure Cloud Service con Azure SQL y tipos geoespaciales
Microsoft Azure te permite publicar un sitio web usando Azure Web Sites o Azure Cloud Service. Si tu app o sitio tiene un perfil más de API (webservices REST) que de website, te conviene publicar un Cloud Service, ya que es más barato a la larga.
Por supuesto, nada es tan fácil como parece. Para una app que envía notificaciones push, partí con una tabla de SQL Azure con un tipo geoespacial (Geography):
Luego en mi controller MVC creo una consulta a la tabla con LINQ:
suscripciones_dbEntities db = new suscripciones_dbEntities();
var res = from s in db.Suscripciones where s.lat != 0 && s.lng != 0 && !string.IsNullOrEmpty(s.handle) select s;
Al ejecutar localmente, la variable res tiene los registros que corresponden. Todo se ve bien. Publico el sitio web en Azure como un Cloud Service, hago la llamada al controller… y nada. No me retorna ningún registro, fallando silenciosamente.
Después de darle vueltas por varias horas, activé IntelliTrace en la instancia de Cloud Service:
Y al revisar los logs de IntelliTrace, me encuentro con esta sorpresa: “Spatial types and functions are not available for this provider because the assembly Microsoft.SqlServer.Types version 10 or higher could not be found“.
Qué sucede? El Cloud Service no tiene instalada la DLL que permite que Entity Framework reconozca el tipo Geography de la tabla.Cómo solucionarlo? Un paquete NuGet que incluye las DLLs y una instrucción de cómo instalarlas:
Después de instalar el paquete, hay que copiar el archivo SqlServerSpatial110.dll desde la carpeta SqlServerTypes\x64 a la carpeta principal del proyecto MVC, y activarle el Copy Always en la propiedad “Copy to Output Directory“. Con esto, al publicar el Cloud Service funcionará correctamente.