J'ai une table avec une colonne de géographie SQL dans ma base de données SQL. J'ai généré des entités pour ma base de données avec EF6. Comme vous le savez, Entitiy Framework génère System.Data.Entity.Spatial.DbGeography
pour le type SQL Geography. J'utilise dapper pour exécuter des requêtes et mapper les résultats dans mes entités générées par EF.
Ma classe d'entité
public partial class Fix
{
public Fix()
{
this.FixUsers = new HashSet<FixUser>();
}
public long FixID { get; set; }
public long UserID { get; set; }
public System.Data.Entity.Spatial.DbGeography Position { get; set; }
public int Radius { get; set; }
public System.DateTime CreatedDate { get; set; }
public virtual MemberProfile MemberProfile { get; set; }
public virtual ICollection<FixUser> FixUsers { get; set; }
}
Requête SQL qui lance une exception
var fix = SqlConnection.Query<Fix>(@"SELECT TOP(1)
f.FixID as FixID,
f.UserID as UserID,
f.Radius as Radius,
f.CreatedDate as CreatedDate,
f.Position as Position
FROM [Fix] f
WHERE f.FixID = @fixId", new { fixId }).FirstOrDefault();
Voici l'instantané d'exception
Je pense que dapper essaie par défaut de mapper avec Microsoft.SqlServer.Types.SqlGeography
.
Y a-t-il une solution de contournement ici?
ÉDITÉ
Trouvé une solution, créé une classe partielle pour mon entité
public partial class Fix
{
public string PositionString
{
set
{
Position = DbGeography.PointFromText(value, 4326);
}
}
}
Et changé ma requête
var fix = SqlConnection.Query<Fix>(@"SELECT TOP(1)
f.FixID as FixID,
f.UserID as UserID,
f.Radius as Radius,
f.CreatedDate as CreatedDate,
f.Position.ToString() as PositionString
FROM [Fix] f
WHERE f.FixID = @fixId", new { fixId }).FirstOrDefault();
Dapper prend en charge de nombreux types de données courants, mais pas tous. Vous pouvez envisager d'utiliser un paramètre de requête personnalisé - vous pouvez voir comment cette validation ajoute un support personnalisé pour les paramètres de table en tant que DataTable
. Je serais très réticent à ajouter quelque chose qui exige des dépendances supplémentaires, en particulier pour des choses comme EF. Ce qui pourrait être utile à l'avenir, c'est un outil d'enregistrement personnalisable pour les fournisseurs personnalisés (permettant aux données contenues dans les paramètres d'être quelque chose - se déplaçant là où la carte se produit). Cela n'existe pas aujourd'hui cependant.
Si vous voulez vraiment utiliser Dapper, vous pouvez convertir SqlGeography en DbGeography:
DbGeography.FromText(sqlGeo.ToString());
Il suffit donc de faire la conversion en mémoire, ou vous pouvez également utiliser SQL avec EF:
dbContext.Fixes.SqlQuery("SELECT TOP(1)
f.FixID,
f.UserID,
f.Radius,
f.CreatedDate,
f.Position
FROM [Fix] f
WHERE f.FixID = @fixId", new SqlParameter("fixId", fixId)).FirstOrDefault();
ou simplement utiliser Entity Framework de la manière habituelle? Puisque ce n'est pas une requête compliquée :)
dbContext.Fixes.Find(fixId);
Je suis toujours curieux de savoir pourquoi vous interrogez avec Dapper pour ensuite le mapper aux entités de EF