Ilya Leykin
Ilya Leykin

Reputation: 145

How Entity framework works with lambda-expressions in ASP.NET MVC

I'm working with EF code first. There are two classes which define my many to many association tables:

public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string Email { get; set; }

    public virtual ICollection<Habit> Habits { get; set; }
}



public class Habit
{
    [Key]
    public int HabitId { get; set; }

    public virtual ICollection<UserProfile> Users { get; set; }
}

I need to select from my database all habits for current user. I'm very new to c#, and the problem is that I can't understand how to work with complex lambda-expressions. I tried that:

context.Habits.Where(habit => habit.Users
                .Where(user=>user.Email==User.Identity.Name)).ToList()

But it's wrong. Could you please correct my lambda-based query. Thanks.

Upvotes: 0

Views: 1815

Answers (3)

Slauma
Slauma

Reputation: 177133

Because you want to select a specific property (Habits) from the UserProfile entity the most straight-forward way would be to use Select in my opinion:

var habits = context.UserProfiles
    .Where(user => user.Email == User.Identity.Name)
    .Select(user => user.Habits)
    .SingleOrDefault(); // I assume here that the Email is unique

Upvotes: 0

Tallmaris
Tallmaris

Reputation: 7590

Why not add a DbSet<UserProfile> to your context and then do:

context.Users.Include("Habits")
       .First(user => user.Email == User.Identity.Name)
       .Habits;

If you want to avoid the above and rather fix the query you should do:

context.Habits.Where(habit =>                   
           habit.Users.Any(user=>user.Email==User.Identity.Name)).ToList();

Any returns true if any item in the IEnumerable satisfies the condition.

Upvotes: 2

Omada
Omada

Reputation: 784

Try using Select (or SelectMany if you want a single flattened list) for the first lambda expression:

context.Habits.Select(habit =>
    habit.Users.Where(user => user.Email == User.Identity.Name)
    ).ToList()

The problem is that Where requires that the lambda expression return a boolean, and it was returning an IEnumerable<UserProfile>.

Upvotes: 0

Related Questions