2010-05-05 2 views
7

Это мой запрос:Linq к Entities левый РЕГИСТРИРУЙТЕСЬ

from forum in Forums 
    join post in Posts on forum equals post.Forum into postGroup  

    from p in postGroup  
    where p.ParentPostID==0 

    select new 
    { 
     forum.Title, 
     forum.ForumID, 
     LastPostTitle = p.Title, 
     LastPostAddedDate = p.AddedDate   
    }).OrderBy(o=>o.ForumID) 

В настоящее время Регистрация не осталось присоединиться, то есть, если какой-то форум не пост, который принадлежит к нему, он не будет возвращен ,
Форум без сообщений должен быть возвращен с нулевыми (или по умолчанию) значениями свойств сообщения.

UPDATE

Набор результат должен быть какой-то вещи, как, что:

ForumId | ForumTitle | LastPostTitle | LastPostAddedDate 
--------+------------+---------------+------------------ 
4  | Sport | blabla  |  12/4/2010 
4  | Sport | blabla  |  15/4/2010 
6  | Games | blabla  |  1/5/2010 
7  | Flame |    | 
+0

ваш 'от р в postGroup' должно быть 'от р в postGroup.DefualtIfEmpty()' –

ответ

0
public class ForumPosts 
    { 
     public Forum Forum { get; set; } 
     public IQueryable<Post> Posts { get; set; } 
    } 

    public class DisplaySet 
    { 
     public string Name { get; set; } 
     public string PostTile { get; set; } 
    } 



      //left outer join 
      using (ClassLibrary1.Entities context = new Entities()) 
      { 
       var allForums = from f in context.Fora 
           select new ForumPosts 
           { 
            Forum = f, 
            Posts = context.Posts.Where(x=> x.ForumId == f.ForumId) 

           }; 
       List<DisplaySet> ds = new List<DisplaySet>(); 

       foreach (var forum in allForums) 
       { 
        if (forum.Posts.AsEnumerable().Count() != 0) 
        { 
         foreach (var post in forum.Posts) 
         { 
          ds.Add(new DisplaySet(){ Name = forum.Forum.Name, PostTile = post.PostValue}); 
         } 
        } 
        else 
         ds.Add(new DisplaySet(){ Name = forum.Forum.Name, PostTile = string.Empty}); 
       } 

       foreach (var item in ds) 
       { 
        Console.WriteLine(string.Format("{0} || {1}",item.Name,item.PostTile)); 
       } 


      } 



//This produces the following LINQ query which is right 
SELECT 
[Project1].[ForumId] AS [ForumId], 
[Project1].[Name] AS [Name], 
[Project1].[C1] AS [C1], 
[Project1].[PostId] AS [PostId], 
[Project1].[PostValue] AS [PostValue], 
[Project1].[ForumId1] AS [ForumId1] 
FROM (SELECT 
    [Extent1].[ForumId] AS [ForumId], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[PostId] AS [PostId], 
    [Extent2].[PostValue] AS [PostValue], 
    [Extent2].[ForumId] AS [ForumId1], 
    CASE WHEN ([Extent2].[PostId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM [dbo].[Forum] AS [Extent1] 
    LEFT OUTER JOIN [dbo].[Post] AS [Extent2] ON [Extent2].[ForumId] = [Extent1].[ForumId] 
) AS [Project1] 
ORDER BY [Project1].[ForumId] ASC, [Project1].[C1] ASC 
+0

это не делает то, что мне нужно – shivesh

+0

Когда я получаю allForums, я проверяю, есть ли счет post = 0, затем я печатаю No Posts else, я печатаю все сообщения для Форума. Это то, что вы хотите??? – chugh97

+0

Почему вы не используете предложение join? Результирующий набор не тот, который я хочу, ваш «форум» и все его сообщения. Но я хочу вернуть форумы за сообщение (JOIN)! – shivesh

1
var allforums = from f in context.Fora.Include("Posts") 
          select f; 

Этот запрос выдает те же результаты, как

  var allForums = from f in context.Fora 
          select new ForumPosts 
          { 
           Forum = f, 
           Posts = context.Posts.Where(x=> x.ForumId == f.ForumId) 
+0

, да, и как это мне помогает? – shivesh

1

Вот код, чтобы помочь вам работать с Left Присоединиться Ссылка

private class EntityRole 
    { 
     public int EntityId { get; set; } 
     public int RoleId { get; set; } 
    } 

    private IList<EntityRole> GetSourceEntityRole() 
    { 
     var list = new List<EntityRole>() {new EntityRole(){EntityId = 123, RoleId = 1}, 
              new EntityRole(){EntityId = 123, RoleId = 2}, 
              new EntityRole(){EntityId = 123, RoleId = 3}, 
              new EntityRole(){EntityId = 123, RoleId = 4}}; 

     list.Reverse(); 

     return list; 
    } 

    private IList<EntityRole> GetEmptyEntityRole() 
    { 
     var list = new List<EntityRole>(); 

     return list; 
    } 

    public void TestToDelete() 
    { 
     var source = this.GetSourceEntityRole(); 
     var destination = this.GetEmptyEntityRole(); 

     this.TestLeftJoin(source, destination); 
    } 

    private void TestLeftJoin(IList<EntityRole> source, IList<EntityRole> destination) 
    { 
     var inserting = this.GetMissing(source, destination); 
     var deleting = this.GetMissing(destination, source); 

     this.Enumerate("Source", source); 
     this.Enumerate("Destination", destination); 

     this.Enumerate("Deleting", deleting); 
     this.Enumerate("Inserting", inserting); 
    } 

    private IEnumerable<EntityRole> GetMissing(IList<EntityRole> sourceEntities, IList<EntityRole> destinationEntities) 
    { 
     return from source in sourceEntities 
       join dest in destinationEntities on source.RoleId equals dest.RoleId into joined 
       from source2 in joined.DefaultIfEmpty() 
       where source2 == null 
       select source; 
    } 

    private void Enumerate(string source, IEnumerable<EntityRole> roles) 
    { 
     foreach (var item in roles) 
     { 
      Console.WriteLine("{0}:{1}", source, item.RoleId); 
     } 
    } 
+1

DefaultIfEmpty() не поддерживается инфраструктурой Entity в Net 3.5 – shivesh

+0

Я хотел бы видеть код, который помогает левому соединению с Zelda;) –

1
Forums 
    .GroupJoin(PostGroup, f => f.ID, p => p.ForumID, (f, p) => new { Forum = f, PostList = p }) 
    .Where(anon => anon.PostList.Any(pl => pl.ParentPostID.Equals(0))) 
    .OrderBy(anon => anon.Forum.ForumID) 
    .Select(anon => new 
    { 
     Title = anon.Forum.Title, 
     ForumID = anon.Forum.ForumID, 
     LastPostTitle = anon.PostList.FirstOrDefault().Title, 
     LastPostAddedDate = anon.PostList.FirstOrDefault().AddedDate, 
    }); 

что-то похожее на это. Я был не слишком уверен, потому что на самом деле я не рассматривал модель данных, но GroupJoin должен быть очень похож на LEFT OUTER JOIN, даже если это не реально делает это в SQL.

1

попробовать что-то вроде этого:

from forum in Forums 
join post in Posts on forum equals post.Forum into postGroup  

// from p in postGroup  
// where p.ParentPostID==0 

select new 
{ 
    forum.Title, 
    forum.ForumID, 
    LastPostTitle = postGroup.FirstOrDefault(p => p.ParentPostID==0).Title, 
    LastPostAddedDate = (DateTime?)postGroup.FirstOrDefault(p => p.ParentPostID==0).AddedDate   
}).OrderBy(o=>o.ForumID) 

свойства, которые возвращают пустой слева присоединиться также должны быть обнуляемым. Итак, int => int? и DateTime => DateTime? и т.д ..

1

если не ошибка:

var list = from forum in Forums.DefaultItIfEmpty() 
from post in Posts.DefaultItIfEmpty() 
where forum.forum_id == post.forum_id && post.ParentPostID==0 
select new 
{ 
    forum.Title, 
    forum.ForumID, 
    LastPostTitle = p.Title, 
    LastPostAddedDate = p.AddedDate   
}).OrderBy(o=>o.ForumID) 
1

Пробовали ли вы что-то вроде:

from forum in Forums 
from posts in (Posts.Where(qPosts=> forum.ForumId == qPosts.ForumId)).DefaultIfEmpty() 
where posts.ParentPostID == 0 
orderby forum.ForumId 
select new 
{ 
    forum.Title, 
    forum.ForumID, 
    LastPostTitle = posts.Title, 
    LastPostAddedDate = posts.AddedDate 
} 
Смежные вопросы