0

I have LINQ query like this

ApplicationDbContext context = new ApplicationDbContext();

IEnumerable<InvitationMails> customers = context.InvitationMails
            .Where(c => c.LinkStart == null)
            .AsEnumerable()
            .Select(c => {
                c.LinkStart = start;
                return c;
            });

I need to select LinkStart, LinkEnd, and Link columns with checking for null values like this.

.Where(c => c.LinkStart == null)
.Where(c => c.LinkEnd == null)
.Where(c => c.Link == null)

But how do write query for select?

Model

public string Link { get; set; }
public DateTime? LinkStart { get; set; }
public DateTime? LinkEnd { get; set; }
4
  • Are LinkStart, LinkEnd, and Link of the same Type? Commented Mar 11, 2017 at 9:25
  • Link start and LinkEnd yes. Link not Commented Mar 11, 2017 at 9:25
  • Could you give me the types? Commented Mar 11, 2017 at 9:30
  • Instead of creating a struct for your selections, you can simply select as an anonymous object. Take a look at my answer. Commented Mar 11, 2017 at 11:13

2 Answers 2

4

LINQ allows you to select any combination of properties you want without having to define a type for every combination of properties. When you don't specify type in your Select, your selections are morphed into an anonymous object. This is how you can do it:

var result = context.InvitationMails
             .Where(c => c.LinkStart == null && c.LinkEnd == null && c.Link == null)
             .Select(c => new { c.LinkStart, c.LinkEnd, c.Link });

result is an anonymous object with the properties specified.

Note that, as long as you are not required to pass the result object to any method, or return result from the current method, you are good to go. However, if you do need to do any of that, you have to create a class (or struct) for that (or, you could make do with object at the expense of type inference/intellisense).

Also note that you don't have to chain the Where one after another, you can simply use boolean operators like && to separate your conditions.

Edit: If your model is composed entirely of those three properties, you don't need a Select at all. You can simply do this:

var result = context.InvitationMails
             .Where(c => c.LinkStart == null && c.LinkEnd == null && c.Link == null);

Note in that case result will not be IQueryable of anonymous types, but of InvitationMail (considering your model's name is InvitationMail).

Sign up to request clarification or add additional context in comments.

Comments

0

Since the properties you are trying to select aren't all of the same type, you need to create a struct if you want to keep them all in the same IEnumerable. An IEnumerable<pair<string, pair<DateTime?, DateTime?>>> would also work, but the struct solution seems cleaner.

public struct Customer
{
   string Link;
   DateTime? LinkStart;
   DateTime? LinkEnd;

   public Customer(string link, DateTime? linkStart, DateTime? linkEnd)
   {
       this.Link = link
       this.LinkStart = linkStart;
       this.LinkEnd = linkEnd;
   }
}

Once you have that then you can do:

        .Where(c => c.LinkStart == null)
        .Where(c => c.LinkEnd == null)
        .Where(c => c.Link == null)
        .Select(c => new Customer(c.Link, c.LinkStart, c.LinkEnd));

4 Comments

You can replace your three where statements with && operator!
Sure, but that isn't what OP asked for.
BTW it would be better if you suggest to use && instead of multiple where.
Why not just use anonymous objects? If the OP happens to selection another combination of columns, must they create another struct for that? Wouldn't that be very clumsy?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.