Разделение сущности с навигационным свойством на две таблицы с использованием EF4.1 Fluent API - PullRequest
1 голос
/ 07 июля 2011

У меня есть таблица Users и таблица UserProfiles.Пользователь имеет либо ноль, либо только один профиль пользователя.(т.е. отношения один к одному) может кто-нибудь помочь мне использовать свободный API EF4.1 для сопоставления сущности пользователей с таблицами Users и UserProfilesНиже приведены данные таблицы.Также пользователи и AuthProvider имеют отношение один ко многим.

// 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();

          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();

        }
      }

1 Ответ

0 голосов
/ 12 июля 2011

Свойства навигации не сопоставляются непосредственно с таблицами, поэтому необходимо удалить AuthProvider из сопоставления с Users таблицей:

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

Я почти уверен, что уже где-то ответил на этот вопрос.

Edit:

Это отвечает на ваш вопрос. Вы хотели разделить сущность, и это правильное отображение для разбиения сущности. Разделение сущностей не позволяет пользователям без профиля. Как только вы используете его, у каждого пользователя должен быть профиль - это является обязательным условием для разделения сущностей. Ваши варианты:

  • У вас должен быть профиль для каждого пользователя, и после этого вы можете использовать разбиение сущностей и отобразить обе таблицы на одну сущность. Если у вас нет профиля для каждого пользователя, измените базу данных и убедитесь, что у каждого пользователя есть пустой профиль.
  • Если у вас нет профиля для каждого пользователя, и вы не хотите создавать пустые профили, вы не можете использовать разделение сущностей = вы не можете сопоставить эти таблицы с одной сущностью, и вы должны использовать две сущности с отношением один к одному вместо этого.

Как только вы используете разделение сущностей, оно ведет себя точно так же, как и любая другая сущность - оно всегда загружает все свойства, и это является причиной внутреннего соединения. Вы не можете загрузить только половину свойств (кроме проекции, но она по-прежнему выполняет основной запрос внутри).

...