J'ai un système qui doit essentiellement faire une requête comme celle-ci:
SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)
Ceci est assez simple à faire lors de l'utilisation de paramètres SQL à la vanille, il vous suffit de créer votre paramètre d'une manière non typique (où la variable constructeur est un SqlGeometryBuilder que j'utilise pour créer un rectangle):
command.Parameters.Add(new SqlParameter
{
UdtTypeName = "geometry",
Value = builder.ConstructedGeometry,
ParameterName = "@paremeter"
});
Maintenant, quand j'essaie de faire ceci en utilisant dapper, j'ai une erreur qu'il ne peut pas comprendre comment l'utiliser comme paramètre. Quelqu'un qui a ce travail, ou des conseils sur la façon d'activer cela? J'ai une solution de contournement, mais cela implique d'utiliser la représentation sous forme de chaîne et de la convertir en un type de géométrie dans ma requête SQL. Je ne veux vraiment pas ça.
Pour répondre au commentaire, l'erreur que j'obtiens est "Le paramètre membre de type Microsoft.SqlServer.Types.SqlGeometry ne peut pas être utilisé comme valeur de paramètre". En d'autres termes, dapper ne sait pas comment traiter un objet SqlGeometry en tant que paramètre.
La clé de l'implémentation de paramètres spécifiques à la base de données étranges et merveilleux se résume à SqlMapper.IDynamicParameters
Cette interface simple possède un seul point de terminaison:
public interface IDynamicParameters
{
void AddParameters(IDbCommand command);
}
Dapper a déjà une implémentation générique de base de données de cette interface appelée: DynamicParameters
qui vous permet de gérer les valeurs de sortie et de retour.
Pour imiter ce genre de choses spatiales, je voudrais essayer quelque chose comme:
public class SpatialParam : SqlMapper.IDynamicParameters
{
string name;
object val;
public SpatialParam(string name, object val)
{
this.name = name;
this.val = val;
}
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.Parameters.Add(new SqlParameter
{
UdtTypeName = "geometry",
Value = val,
ParameterName = name
});
}
}
Usage:
cnn.Query("SELECT * FROM MyTable WHERE @parameter.STIntersects(MyGeometryColumn)",
new SpatialParam("@parameter", builder.ConstructedGeometry));
Cette implémentation simple de l'interface ne gère qu'un seul paramètre, mais elle peut facilement être étendue pour gérer plusieurs paramètres, soit en passant du constructeur, soit en ajoutant une méthode AddParameter.
DbGeography
SqlGeography
SqlGeometry
DbGeometry
SqlHierarchyId
Donc, avec les dernières bibliothèques; cela devrait simplement fonctionner.