David Glenn
David Glenn

Reputation: 24522

many to many mapping in entity framework code first

I'm using Entity Framework 4 CTP5 Code First and I have a model along the lines of:

public class User {
   public int UserId { get; set; }
   public string Email { get; set; }
   public ICollection<Customer> TaggedCustomers { get; set; }
}
public class Customer {
  public int CustomerId { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public ICollection<User> TaggedBy { get; set; }
}

There is a many to many relationship where a User can 'tag' a Customer and a Customer can be 'tagged' by many users. I have a working DbContext and I can query customers using

 var customers = DbContext.Customers.Include(c => c.TaggedBy);

But each customer will have all users that have tagged the customer. How do I restrict the TaggedBy collection to just result with a specifed UserId?

I've tried along the lines of DbContext.Customers.Include(c => c.TaggedBy.Select(x => x.Id == userId)); but that throws an error.

Upvotes: 3

Views: 1793

Answers (2)

takepara
takepara

Reputation: 10433

EF Feature CTP5: Fluent API Samples - ADO.NET team blog - Site Home - MSDN Blogs

modelBuilder.Entity<Product>() 
    .HasMany(p => p.Tags)
    .WithMany(t => t.Products)
    .Map(m =>
        {
            m.MapLeftKey(p => p.ProductId, "CustomFkToProductId");
            m.MapRightKey(t => t.TagId, "CustomFkToTagId");
        }); 

Code First Mapping Changes in CTP5 - ADO.NET team blog - Site Home - MSDN Blogs

modelBuilder.Entity<Product>()
    .HasMany(p => p.SoldAt)
    .WithMany(s => s.Products)
    .Map(mc => {
        mc.ToTable("ProductsAtStores");
        mc.MapLeftKey(p => p.Id, "ProductId");
        mc.MapRightKey(s => s.Id, "StoreId");
    });

Upvotes: 6

Steven K.
Steven K.

Reputation: 2106

Mark your collections as virtual and then you can easily do:

public class User
{
    public int UserId { get; set; }
    public string Email { get; set; }
    public virtual ICollection<Customer> TaggedCustomers { get; set; }
}

public class Customer
{
    public int CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<User> TaggedBy { get; set; }
}

using(var context = new MyDbContext())
{
    var user = context.Users.Single(o => o.UserId == 0);
    var customers = user.TaggedCustomers;
}

Results in much cleaner code in my opinion.

Upvotes: 0

Related Questions