开发者

Splitting an Entity with navigational property into two tables using EF4.1 Fluent API

I have a Users table and a UserProfiles table. A user has either zero or only one User profile. (i.e one to one relationship) can someone help me use EF4.1 fluent API to Map the Users Entity to the both Users and UserProfiles tables. Below is the table details. Also Users and AuthProvider have a one to Many relationship.

// 1. Users Table has the columns(UserId(PK), UserName, Email, AuthProviderId(FK))
// 2. UserProfiles Table has columns(UserId(PK/FK), FirstName, MiddleName,LastName)
// 3. AuthProvider Table has columns (AuthProviderId(PK), AuthName)

    public class User {
        public User() {
          Id = Guid.NewGuid();
        }
        public virtual Guid Id { get; private set; }

        public virtual string Username { get; set; }
        public virtual string Email { get; set; }
        public virtual AuthProvider AuthProvider { get; set; }

        public virtual string FirstName { get; set; }
        public virtual string MiddleName { get; set; }
        public virtual string LastName { get; set; }
      }

    public class AuthProvider {
        public AuthProvider() {
          Id = Guid.NewGuid();
        }
        public virtual Guid Id { get; private set; }
        public virtual string Name { get; set; }   
        public virtual ICollection<User> Users { get; set; }
      }

    // This is the Mappings
     public class UserConfiguration : EntityTypeConfiguration<User> {
        public UserConfiguration() {
          HasKey(x => x.Id).Property(x => x.Id).HasColumnName("UserId").IsRequired();
          Property(x => x.Username).HasColumnName("Username").IsRequired();
          Property(x => x.Email).HasColumnName("Email").IsRequired();

          Property(x => x.FirstName).HasColumnName("FirstName").IsOptional();
          Property(x => x.MiddleName).HasColumnName("MiddleName").IsOptional();
          Property(x => x.LastName).HasColumnName("LastName").IsOptional();

          开发者_JAVA百科HasRequired(x => x.AuthProvider).WithMany(x => x.Users).Map(x => x.MapKey("AuthProviderId"));

          Map(mc => {
            mc.Properties(x => new {
              x.Id,
              x.Username,
              x.Email,
              x.AuthProvider
            });
            mc.ToTable("Users");
          });

          Map(mc => {
            mc.Properties(x => new { x.Id, x.FirstName, x.MiddleName, x.LastName });
            mc.ToTable("UserProfiles");
          });
        }
      }


     public class AuthProviderConfiuration : EntityTypeConfiguration<AuthProvider> {
        public AuthProviderConfiuration() {
          ToTable("AuthProviders");
          HasKey(x => x.Id).Property(x => x.Id).HasColumnName("AuthProviderId").IsRequired();
          Property(x => x.Name).HasColumnName("ProviderName").IsRequired();

        }
      }


Navigation properties are not mapped directly to tables so you must remove AuthProvider from mapping to Users table:

      Map(mc => {
        mc.Properties(x => new {
          x.Id,
          x.Username,
          x.Email
        });
        mc.ToTable("Users");
      });

I'm pretty sure I already answered this question somewhere.

Edit:

This answers your question. You wanted entity splitting and this is correct mapping for entity splitting. Entity splitting doesn't allow users without profile. Once you use it every user must have a profile - that is prerequisite for entity splitting. Your options are:

  • You must either have profile for each user and after that you can use entity splitting and map both tables to single entity. If you don't have profile for each user either modify your database and make sure that every user has empty profile.
  • If you don't have profile for each user and you don't want to create empty profiles you cannot use entity splitting = you cannot map these tables to single entity and you must use two entities with one-to-one relation instead.

Once you use entity splitting it behaves exactly as any other entity - it always loads all properties and that is a reason for inner join. You cannot load only half of the properties (except the projection but it still executes main query internally).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜