views:

92

answers:

1

The site I am working on has the concept of a User and a Site. A User can join the global site and create mini sites within (www.globalsite.com/minisite). The Users can also Follow other mini sites created by other users. Think about it like if Twitter allowed you to join with one set of credentials and create different accounts, one for @personal use, @business use etc.

I am using EF CTP4 and using code first. I am just not sure if I am designing my model correctly.

public class User : IEntity
{
    public virtual ICollection<Site> Sites{ get; set; }
    public virtual ICollection<Site> Following{ get; set; }
    ....
}

public class Site: IEntity
{
    public virtual User User{ get; set; }
    public virtual ICollection<User> Following{ get; set; }
    ....
}

And here are me mappings:

public class UserMap : EntityConfiguration<User>
    {
        public UserMap()
        {
            HasKey(u => u.Id);
            Property(u => u.Id).IsIdentity();
            Property(u => u.Name).IsRequired().IsVariableLength().HasMaxLength(75);
            Property(u => u.Email).IsRequired().IsVariableLength().HasMaxLength(75);
            Property(u => u.PasswordHash).IsRequired().IsVariableLength().HasMaxLength(215);
            Property(u => u.PasswordSalt).IsRequired().IsVariableLength().HasMaxLength(88);
            Property(u => u.IsConfirmed);
            Property(u => u.LastActivityAt);
            Property(u => u.CreatedAt);
            Property(u => u.InternalRole);
            MapSingleType(u => new
                                   {
                                       u.Id,
                                       u.Name,
                                       u.Email,
                                       u.PasswordHash,
                                       u.PasswordSalt,
                                       u.IsConfirmed,
                                       Role = u.InternalRole,
                                       u.LastActivityAt,
                                       u.CreatedAt
                                    }).ToTable("User");
        }
    }

 public class SiteMap : EntityConfiguration<Site>
    {
        public SiteMap()
        {
            HasKey(s => s.Id);
            Property(s => s.Id).IsIdentity();
            Property(s => s.HasDonationPage);
            Property(s => s.IsActive);
            Property(s => s.IsAdminRestricted);
            Property(s => s.IsPrivate);
            Property(s => s.Slug).IsRequired().IsVariableLength().HasMaxLength(125);
            Property(s => s.CreatedAt);
            MapSingleType(s => new
                                   {
                                   s.Id,
                                   UserId = s.User.Id,
                                   ThemeId = s.Theme.Id,
                                   s.HasDonationPage,
                                   s.IsActive,
                                   s.IsAdminRestricted,
                                   s.IsPrivate,
                                   s.Slug,
                                   s.CreatedAt
                                   }).ToTable("Sites");
        }
    }

Is this correct or should it be modeled differently? I used to have the relationships mapped manually with the:

Relationship(u => u.SitesFollowing).FromProperty(s => s.UsersFolling);

syntax, but now that I have upgraded to CPT4, that no longer works. I expected EF to create one relationship table in the DB called SiteFolling_UserFollowing with a SiteId and UserId but it created a Site_User table with SiteId(PK) and UserId(FK), a Following_Site with Following_Id(PK) and Site_Id(FK) and a Following_User table with Following_Id(PK) and User_Id(FK).

Any guidance would be great, thanks!

A: 

If you want to map a many-to-many relationship (User has many Sites) you can do the following in CTP4 in side the UserMap:

this.HasMany(u => u.Sites).WithMany();

You can alternatively describe the table where the many-to-many relationship lives:

this.HasMany(u => u.Sites).WithMany().Map(new StoreTableName("SiteFollowing_UserFollowing", "dbo"), (u, s) => new { UserId = u.Id, SiteId = s.Id });

If this is not what you're looking for, do let me know. Cheers!

TheCloudlessSky