Search code examples
c#linqquery-expressions

LINQ query expressions and extension methods


How to make this expression using the methods of exptension, but (!) not using anonymous types?

from p in posts
               join u in context.oxite_Users on p.CreatorUserID equals u.UserID
               join pa in context.oxite_PostAreaRelationships on p.PostID equals pa.PostID
               join a in context.oxite_Areas on pa.AreaID equals a.AreaID
               let c = getCommentsQuery(p.PostID)
               let t = getTagsQuery(p.PostID)
               let tb = getTrackbacksQuery(p.PostID)
               let f = getFilesQuery(p.PostID)
               where p.State != (byte)EntityState.Removed
               orderby p.PublishedDate descending
               select new Post
               { area = a, comments = c } e.t.c.

Solution

  • The key here is to introduce a tuple that encapsulates the combined state of the join operations and other lets. I can't repro your environment just from that, but here's a limited example that should make it clear(ish);

    using System.Linq;
    static class Program
    {
        static void Main()
        {
            var users = new User[0]; // intentionally 0; only exists to prove compiles
            var orders = new Order[0];
    
            var query = users.Join(orders, user => user.UserId, order => order.OrderId, (user,order) => new UserOrderTuple(user,order))
                .Where(tuple => tuple.State != 42).OrderByDescending(tuple => tuple.Order.OrderId)
                .Select(tuple => new ResultTuple { Comment = tuple.Comment });
        }
    }
    
    class ResultTuple
    {
        public string Comment { get; set; }
    }
    class UserOrderTuple
    {
        public UserOrderTuple(User user, Order order)
        {
            User = user;
            Order = order;
            Comment = "some magic that gets your comment and other let";
            State = 124;
        }
        public string Comment { get; private set; }
        public int State { get; private set; }
        public User User { get; private set; }
        public Order Order { get; private set; }
    }
    class User
    {
        public int UserId { get; set; }
    }
    class Order
    {
        public int UserId { get; set; }
        public int OrderId { get; set; }
    }