订单在EF linq里面

时间:2018-03-30 16:29:26

标签: c# sql-server entity-framework linq entity-framework-6

我的表Sites包含相关表PhotosPhotosSiteId上获得了FK。 照片的字段PhotoNumber的值可以等于1,2或3。 如果Site Photos PhotoNumber = 1,2和3,我需要知道。 我尝试了类似的东西,但是我无法通过DateDatePhotos中的索引字段)在linq内部订购照片,以便在有序列表中使用Any() ,并订购一次,以优化这一点。我很困惑,如果我应该订购它?

  var sites = (from site in context.Sites
               select new
               {
                   Site = site,
                   Cam1 = context.Photos.Any(p => p.SiteId == site.SiteID && p.PhotoNumber == 1),
                   Cam2 = context.Photos.Any(p => p.SiteId == site.SiteID && p.PhotoNumber == 2),
                   Cam3 = context.Photos.Any(p => p.SiteId == site.SiteID && p.PhotoNumber == 3)
               }).ToList();

我知道最简单的方法可能是:

var sitesToCameraIds = (from photo in context.Photos 
    select new { SiteId = photo.SiteId, CameraId = photo.PhotoNumber})
    .Distinct()
    .ToList().OrderBy(p => p.SiteId);

但它会非常慢,因为它需要检查所有照片,以便在未编入索引的字段PhotoNumber上进行区分(不能只是索引的索引),而是我想使用{ {1}}就第一场比赛停止搜索而言。

照片桌:

enter image description here

网站表:

enter image description here

3 个答案:

答案 0 :(得分:0)

  

我需要知道Site是否有PhotoNumber = 1,2和的照片   3

var photoNumbers = new List<int> {1,2,3}

var isSiteHasAnyPhotos = context
  .Photos
  .Any(p => p.SiteId = siteId && photoNumbers.Contains(q.PhotoNumber))

答案 1 :(得分:0)

如果您只想知道每个网站是否存在每张照片,您可以加入一次并转动结果:

var sites =
    from site in context.Sites
    join photo in context.Photos on site.Id equals photo.SiteId into photos
    from photo in photos.DefaultIfEmpty()
    group photo by site into g
    select new
    {
        Site = g.Key,
        HasPhotoNumber1 = g.Any(x => x.PhotoNumber == 1),
        HasPhotoNumber2 = g.Any(x => x.PhotoNumber == 2),
        HasPhotoNumber3 = g.Any(x => x.PhotoNumber == 3)
    };

执行单个LEFT OUTER JOIN会更有效率,并确保结果中仍会返回没有任何照片的网站。

另外,请确保已将SiteId编入索引。例如:

CREATE UNIQUE NONCLUSTERED INDEX [IX_Photos] ON [Photos]
(
   [SiteId] ASC,
   [PhotoNumber] ASC
);

答案 2 :(得分:0)

如果您没有从SitesPhotos的EF导航属性为您提供加入,您可以手动执行加入:

var sites = (from site in context.Sites
             join p in context.Photos on site.SiteID equals p.SiteId into pj
             select new {
                 Site = site,
                 Cam1 = pj.Any(p => p.PhotoNumber == 1),
                 Cam2 = pj.Any(p => p.PhotoNumber == 2),
                 Cam3 = pj.Any(p => p.PhotoNumber == 3)
             }).ToList();