Я использую asp. net core 3.1 с провайдером инфраструктуры ядра. Я хочу найти пользователей в пределах указанных c километров в космосе DB sql API. Но возникли проблемы. Введите код подробно ниже.
Класс сущности ApplicationUser:
using Microsoft.AspNetCore.Identity;
namespace TestApp_Backend_API.Entities
{
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string ZipCode { get; set; }
public GeoLocation DefaultLocationCoordinates { get; set; }
}
}
Класс геолокации:
using System;
using Newtonsoft.Json;
namespace TestApp_Backend_API.Entities
{
public class GeoLocation
{
public GeoLocation(double lon, double lat)
{
Type = "Point";
if (lat > 90 || lat < -90) { throw new ArgumentException("A latitude coordinate must be a value between -90.0 and +90.0 degrees."); }
if (lon > 180 || lon < -180) { throw new ArgumentException("A longitude coordinate must be a value between -180.0 and +180.0 degrees."); }
Coordinates = new double[2] { lon, lat };
}
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("coordinates")]
public double[] Coordinates { get; set; }
public double? Lat() => Coordinates?[1];
public double? Lon() => Coordinates?[0];
}
}
DbContext:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using TestApp_Backend_API.Entities;
using TestApp_Backend_API.Helpers;
namespace TestApp_Backend_API.DbContexts
{
public class TestAppContext : IdentityDbContext<ApplicationUser>
{
public TestAppContext(DbContextOptions options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.HasDefaultContainer("Users");
builder.Entity<IdentityUser>().ToContainer("Users");
builder.Entity<ApplicationUser>().ToContainer("Users");
builder.Entity<IdentityUserRole<string>>().ToContainer("UserRoles");
builder.Entity<IdentityUserLogin<string>>().ToContainer("UserLogins");
builder.Entity<IdentityUserClaim<string>>().ToContainer("UserClaims");
builder.Entity<IdentityRole>().ToContainer("Roles");
builder.Entity<IdentityUserToken<string>>().ToContainer("UserTokens");
builder.Entity<ApplicationUser>(x =>
{
x.Property(g => g.DefaultLocationCoordinates)
.HasJsonConversion();
});
}
}
}
Расширение HasJsonConversion Метод:
public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder)
{
ValueConverter<T, string> converter = new ValueConverter<T, string>(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<T>(v));
ValueComparer<T> comparer = new ValueComparer<T>(
(l, r) => JsonConvert.SerializeObject(l) == JsonConvert.SerializeObject(r),
v => v == null ? 0 : JsonConvert.SerializeObject(v).GetHashCode(),
v => JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(v)));
propertyBuilder.HasConversion(converter);
propertyBuilder.Metadata.SetValueConverter(converter);
propertyBuilder.Metadata.SetValueComparer(comparer);
return propertyBuilder;
}
Я сохраняю DefaultLocationCoordinates, как это в cosmos db:
"DefaultLocationCoordinates": "{\"type\":\"Point\",\"coordinates\":[31.9,-4.8]}"
Теперь я хочу запрашивать пользователей, как это:
select * from c where
ST_DISTANCE(c.DefaultLocationCoordinates, {'type': 'Point', 'coordinates':[31.9, -4.8]}) < 90000
Но он ничего не возвращает, при сохранении DefaultLocationCoordinates, как это работает нормально:
"DefaultLocationCoordinates": {
"type": "Point",
"coordinates": [
31.9,
-4.8
]
},
Я сохраняю DefaultLocationCoordinates, как показано ниже, потому что, если эта проблема https://github.com/dotnet/efcore/issues/17317
"DefaultLocationCoordinates": "{\"type\":\"Point\",\"coordinates\":[31.9,-4.8]}"
Может ли кто-нибудь предоставить решение для этого, чтобы я мог выполнить этот запрос:
select * from c where
ST_DISTANCE(c.DefaultLocationCoordinates, {'type': 'Point', 'coordinates':[31.9, -4.8]}) < 90000
Пример данных в космосе db:
{
"Id": "f38fb31e-49bd-42bb-9a00-d560168bd560",
"DefaultLocationCoordinates": "{\"type\":\"Point\",\"coordinates\":[-74.505312,40.575405]}",
"Discriminator": "ApplicationUser",
"FirstName": "Tom",
"id": "f38fb31e-49bd-42bb-9a00-d560168bd560",
"_rid": "4sM9AP3bWYwGAAAAAAAAAA==",
"_self": "dbs/4sM9AA==/colls/4sM9AP3bWYw=/docs/4sM9AP3bWYwGAAAAAAAAAA==/",
"_etag": "\"00000000-0000-0000-081a-745b667201d6\"",
"_attachments": "attachments/",
"_ts": 1585741276
}