mVC3 EF4.1 Ошибка проектирования модели - PullRequest
1 голос
/ 03 января 2012

EF 4.1 в MVC3 и отложенной загрузке с использованием кода первой модели

С трудностями при проектировании правильных моделей. Пожалуйста, посмотрите и дайте мне знать, что я делаю не так. Как я могу это исправить.

Я использую API членства для создания учетной записи. После того, как учетная запись создана успешно. Я перенаправляю, чтобы создать запись контакта автоматически. contactId (автоматически сгенерированная база данных), userid (хранит идентификатор пользователя, сгенерированный api членства)

Модели:

public class Contact
{
   public int ContactID { set; get; }
   public string UserId { set; get; }
   public string LastName { set; get; }
   public int? CompanyID { set; get; } // not sure if I need this as it will be NULL
   public virtual Company CompanyInfo { set; get; }
}

Далее пользователь может щелкнуть ссылку «Создать компанию» или выйти из системы и войти позже, чтобы создать запись о компании.

public class Company
{    
  public int CompanyID { set; get; }
  public int ContactID { set; get; }
  public string CompanyName { set; get; }
  public virtual Contact Contacts { set; get; }
}

Когда пользователь решает создать запись о компании, я проверяю, существует ли компания, если она существует, я просто показываю контактную информацию и информацию о компании ИЛИ, если не найден, я перенаправляю на создание компании.

public ActionResult chckifCompanyFound()
    {
        int contactId = 1; //Assuming I retrieved the value 
        //I think I should get the data from Company table, if company data found then contact data could be retrieved using lazy loading? 
       Company c= db.Company.Include(c => c.Contacts).Where(x => x.ContactID == contactId).FirstOrDefault();
      if(c == null)
          //redirect to create company
      else
         // view data from c company object
    }

В настоящее время отображается исключение при попытке создать запись контакта после того, как членство API создает учетную запись. Я создаю запись так:

Contact contact = new Contact();
contact.UserId = userId;
contact.LastName = lastName;
db.Contacts.Add(contact);
db.SaveChanges();

Исключение:
Невозможно определить основной конец ассоциации между типами D.Models.Contact и D.Models.Company. Основной конец этой ассоциации должен быть явно сконфигурирован с использованием API свободного взаимодействия или аннотаций данных.

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 03 января 2012

Ответ в вашем исключении: Основной конец этой ассоциации должен быть явно сконфигурирован с использованием свободно распространяемого API-интерфейса или аннотаций данных.

Однако, похоже, у вас естьОт 1 до 0..1 здесь: каждая компания должна иметь ровно 1 контакт, но каждый контакт может принадлежать ни одной или 1 компании.Это действительно твое намерение?

Мне кажется, что вы действительно ищете отношения 1 к *, где каждая компания может иметь МНОГИЕ контакты, и каждый контакт принадлежит ни одной или 1 компании.

Аннотации данных

public class Company // the principal
{    
  public int CompanyID { set; get; }
  //public int ContactID { set; get; } Company is the principal
  public string CompanyName { set; get; }
  public virtual ICollection<Contact> Contacts { set; get; } // has many contacts
}
public class Contact
{
   public int ContactID { set; get; }
   public string UserId { set; get; }
   public string LastName { set; get; }

   // you do need CompanyId, but it will be nullable in the db
   public int? CompanyID { set; get; } 
   [ForeignKey("CompanyID")] 
   public virtual Company CompanyInfo { set; get; }
}

Свободный API Примечание: при свободном API вашей сущности не требуется атрибут [ForeignKey]

modelBuilder.Entity<Company>()
    .HasMany(principal => principal.Contacts)
    .WithOptional(dependent => dependent.CompanyInfo)
    .HasForeignKey(dependent => dependent.CompanyID);
0 голосов
/ 03 января 2012

У вас есть отношение один к одному между Contact и Company, и исключение говорит о том, что EF не может решить, какой главный (имеющий первичный ключ) и какой зависимый (имеющий внешний ключ), потому что навигациясвойства "симметричны".EF требует, чтобы вы указали это явно.

Несколько замечаний об отношениях один-к-одному (с EF их сложнее освоить, чем отношения один-ко-многим и даже многие-ко-многим):

  • EF поддерживает только Связи общих первичных ключей для определения отношения один-к-одному.Это означает, что значения первичного ключа связанных объектов должны быть одинаковыми.И для одного из объектов первичный ключ является внешним ключом в то же время.Вы не можете использовать независимый внешний ключ.

  • Следствием этого пункта является то, что вы можете удалить Contact.CompanyID и Company.ContactID.EF не будет рассматривать эти свойства как свойства внешнего ключа.

  • Вторым следствием является то, что один из первичных ключей не может быть автоматически сгенерированным идентификатором в базе данных, поскольку он всегда должен иметь то же значение, что идругой (основной) объект.

  • Вы должны решить, какой объект является основным, а какой - зависимым.Из вашего описания я бы предположил, что Contact является основным (потому что вы разрешаете иметь контакты без компании), а Company является зависимым (потому что нет никакой компании без контакта).

  • Затем вы можете определить отображение с помощью Fluent API в своем производном контексте:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ...
    
        modelBuilder.Entity<Contact>()
            .HasOptional(ct => ct.CompanyInfo)
            .WithRequired(cm => cm.Contacts);
    
        // ...
    }
    

Я считаю, что это отображение будет автоматически гарантировано (если вы создадите БД с EF)что первичный ключ Contact является идентификатором в базе данных, а первичный ключ Company - нет.Если нет, вы можете отключить это явно:

modelBuilder.Entity<Company>()
    .Property(c => c.CompanyID)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...