UPDATE: After a bit more research it seems a number of my many-to-many mappings aren't working. Hmmm...
I'm upgrading a data access project from EF 4.1 CTP4 to EF 4.1 RC and I'm having trouble with the new EntityTypeConfiguration<T>
setup.
Specifically I'm having an issue with a Many-to-Many relationship. I'm getting a Sequence contains no elements
exception when I'm trying to get the .First()
item.
The particular exception isn't really that interesting. All it's saying is that there are no items BUT I know there should be items in the collection - so there must be an issue with my new mappings.
Here's the code I have so far:
Product Model
public class Product : DbTable
{
//Blah
public virtual ICollection<Tag> Categories { get; set; }
public Product()
{
//Blah
Categories = new List<Tag>();
}
}
BaseConfiguration
public class BaseConfiguration<T> : EntityTypeConfiguration<T> where T : DbTable
{
public BaseConfiguration()
{
this.HasKey(x => x.Id);
this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(x => x.UpdatedOn);
this.Property(x => x.CreatedOn);
}
}
ProductConfiguration
public class ProductConfiguration : BaseConfiguration<Product>
{
public ProductConfiguration()
{
this.ToTable("Product");
//Blah
this.HasMany(x => x.Categories)
.WithMany()
.Map(m =>
{
m.MapLeftKey("Tag_Id");
m.MapRightKey("Product_Id");
m.ToTable("ProductCategory");
});
}
}
Previous CTP4 Mapping the worked!
this.HasMany(x => x.Categories)
.WithMany()
.Map("ProductCategory", (p, c) => new { Product_Id = p.Id, Tag_Id = c.Id });
Can anyone see anything that needs fixing? Let me know if you want me to provide more code.
EDIT: More Code
DbTable
public class DbTable : IDbTable
{
public int Id { get; set; }
public DateTime UpdatedOn { get; set; }
public DateTime CreatedOn { get; set; }
}
Tag
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public string Slug { get; set; }
public bool Visible { get; set; }
public virtual TagType TagType { get; set; }
}
TagConfiguration
public class TagConfiguration : EntityTypeConfiguration<Tag>
{
public TagConfiguration()
{
this.ToTable("Tags");
this.HasKey(x => x.Id);
this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnName("tag_id");
this.Property(x => x.Name).HasMaxLength(300).HasColumnName("tag_name");
this.Property(x => x.Slug).HasMaxLength(500).HasColumnName("tag_slug");
this.Property(x => x.Visible).HasColumnName("tag_visible");
this.HasRequired(x => x.TagType).WithMany(tt => tt.Tags).Map(m => m.MapKey("tagtype_id"));
}
}
Yes, this is a legacy database with naming conventions up to boohai.
I know the Tag
class must be wired up correctly because Product has another property Specialization
which is also mapped to Tag
and it loads correctly. But do note that it's mapped in a one-to-many manner. So it seems to be the many-to-many with Tag
.
I'll start checking out if any many-to-many associations are working.