使用Entity Framework获取距离为N的所有结果

时间:2015-01-22 06:32:46

标签: c# linq entity-framework

我首先使用实体​​框架代码在我的表格中创建了一个具有Geography类型的列。我正在调用linq语句从我的表中获取第一个结果,该结果将我传入的位置与表中的所有位置进行比较。我想要的是返回距我所在地20英里或更远的所有行。

这是我到目前为止所拥有的。

var myLocation = DbGeography.FromText("POINT(-122.453164 37.723057)");

using (var repo = new YogaSpaceRepository())
        {
            YogaSpace space = repo.FirstWithinDistance(myLocation);
        } 

public YogaSpace FirstWithinDistance(DbGeography myLocation)
    {
       var yogaSpace = (from u in context.YogaSpaces
            orderby u.Location.Distance(myLocation)
            select u).FirstOrDefault();

        return yogaSpace;
    }

4 个答案:

答案 0 :(得分:3)

这是我所拥有的,似乎有效。我只返回一个IQueryable并将米设置为英里。

public IQueryable<YogaSpace> AllWithinDistance(DbGeography myLocation)
    {
        var yogaSpace = (from u in context.YogaSpaces
                         orderby u.Location.Distance(myLocation)
                         where u.Location.Distance(myLocation) <= 32187 //20 miles = 32187 meters, 10 miles = 16093 meters, 5 miles = 8047 meters
                         select u);

        return yogaSpace;
    }

生成的sql:

 declare @p3 sys.geography
set @p3=convert(sys.geography,0xE6100000010C6A12BC218DDC42405FEE93A3009D5EC0)
declare @p4 sys.geography
set @p4=convert(sys.geography,0xE6100000010C6A12BC218DDC42405FEE93A3009D5EC0)
exec sp_executesql N'SELECT 
    [Project1].[YogaSpaceId] AS [YogaSpaceId], 
    [Project1].[DateCreated] AS [DateCreated], 
    [Project1].[Name] AS [Name], 
    [Project1].[Rating] AS [Rating], 
    [Project1].[Status] AS [Status], 
    [Project1].[OwnerId] AS [OwnerId], 
    [Project1].[Location] AS [Location], 
    [Project1].[Thumbnail] AS [Thumbnail]
    FROM ( SELECT 
        [Extent1].[Location].STDistance(@p__linq__0) AS [C1], 
        [Extent1].[YogaSpaceId] AS [YogaSpaceId], 
        [Extent1].[DateCreated] AS [DateCreated], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[Rating] AS [Rating], 
        [Extent1].[Status] AS [Status], 
        [Extent1].[OwnerId] AS [OwnerId], 
        [Extent1].[Location] AS [Location], 
        [Extent1].[Thumbnail] AS [Thumbnail]
        FROM [dbo].[YogaSpaces] AS [Extent1]
        WHERE ([Extent1].[Location].STDistance(@p__linq__1)) <= cast(32187 as float(53))
    )  AS [Project1]
    ORDER BY [Project1].[C1] ASC',N'@p__linq__1 [geography],@p__linq__0 [geography]',@p__linq__1=@p3,@p__linq__0=@p4

答案 1 :(得分:1)

  1. 在您的Nuget软件包中管理:安装软件包NetTopologySuite

  2. 在数据库中添加新列- ALTER TABLE TableName 添加位置地理位置; enter image description here

  3. 在您的c#模型中添加新属性-公共点位置{get;组; } 因此,现在每次您需要设置此属性时,都必须将SRID (空间参考系统ID)设置为4326,这是Google地图(WGS84)使用的空间参考系统。

    User u = new User
    {
      Username = "user1",
      FirstName = "Maureen",
      LastName = "Miles",
      Location = new Point(16.3738, 48.2082) 
      {
        SRID = 4326
      }
    };
    
  4. 我们还需要在我们的EF上下文中使用UseNetTopologySuite选项。我们的上下文将如下所示:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      optionsBuilder.UseSqlServer(
       @"my connection string",
       x => x.UseNetTopologySuite());
    }
    

5。现在已经准备就绪,查找700公里内的所有用户:

   Point myLocation = new Point(13.4050, 52.5200)
   {
      SRID = 4326
   };

   var ctx = new MyContext();
   double radiusMeters = 700000;
   User[] usersWithinRadius = ctx.Users.Where(x => x.Location.Distance(myLocation) <= radiusMeters).ToArray();

答案 2 :(得分:0)

public IList<YogaSpace> FirstWithinDistance(DbGeography myLocation, double N)
{
    var spaces = context.YogaSpaces();
    return spaces .Where(y => CalculateDistance(yogaSpace.Location, myLocation) <= N).ToList();
}

此处CalculateDistance返回两点之间的距离,

答案 3 :(得分:-1)

    declare @p3 sys.geography
set @p3=convert(sys.geography,0xE6100000010C6A12BC218DDC42405FEE93A3009D5EC0)
declare @p4 sys.geography
set @p4=convert(sys.geography,0xE6100000010C6A12BC218DDC42405FEE93A3009D5EC0)
exec sp_executesql N'SELECT 
    [Project1].[YogaSpaceId] AS [YogaSpaceId], 
    [Project1].[DateCreated] AS [DateCreated], 
    [Project1].[Name] AS [Name], 
    [Project1].[Rating] AS [Rating], 
    [Project1].[Status] AS [Status], 
    [Project1].[OwnerId] AS [OwnerId], 
    [Project1].[Location] AS [Location], 
    [Project1].[Thumbnail] AS [Thumbnail]
    FROM ( SELECT 
        [Extent1].[Location].STDistance(@p__linq__0) AS [C1], 
        [Extent1].[YogaSpaceId] AS [YogaSpaceId], 
        [Extent1].[DateCreated] AS [DateCreated], 
        [Extent1].[Name] AS [Name], 
        [Extent1].[Rating] AS [Rating], 
        [Extent1].[Status] AS [Status], 
        [Extent1].[OwnerId] AS [OwnerId], 
        [Extent1].[Location] AS [Location], 
        [Extent1].[Thumbnail] AS [Thumbnail]
        FROM [dbo].[YogaSpaces] AS [Extent1]
        WHERE ([Extent1].[Location].STDistance(@p__linq__1)) <= cast(32187 as float(53))
    )  AS [Project1]
    ORDER BY [Project1].[C1] ASC',N'@p__linq__1 [geography],@p__linq__0 [geography]',@p__linq__1=@p3,@p__linq__0=@p4