Используйте MVC 3 и Entity Framework, как мне сопоставить другой экземпляр одного и того же класса с 3 различными свойствами коллекции? - PullRequest
1 голос
/ 03 октября 2011

Итак, я создал следующие связанные классы и пытаюсь использовать Code-First.Я хочу, чтобы класс Quote ссылался на 3 экземпляра класса User по 3 различным именам навигационных свойств, но когда я выполняю DBInitializer для заполнения и создания БД, таблица Quote содержит 6 столбцов вместо ожидаемых 3 столбцов, из которых 3 всегданоль.Навигационные свойства указывают на эти 3 пустых столбца, поэтому всякий раз, когда я указываю на Quote.Manager или одно из трех других свойств, он возвращает нулевое значение вместо фактического менеджера.Как я могу это исправить?

Цитировать класс (я немного не учел, но вы поняли):

using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace QuoteManager.Models
{
    public class Quote
    {
        public int QuoteID { get; set; }

        public virtual int StateID { get; set; }
        public virtual State State { get; set; }

        public virtual int CreatorID { get; set; }
        public virtual User Creator { get; set; }
        public virtual int AgentID { get; set; }
        public virtual User Agent { get; set; }
        public virtual int ManagerID { get; set; }
        public virtual User Manager { get; set; }
    }
}

Класс пользователя:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace QuoteManager.Models
{
    public class User
    {

        public User()
        {
            this.Quotes = new HashSet<Quote>();
            this.CreatedQuotes = new HashSet<Quote>();
            this.ManagedQuotes = new HashSet<Quote>();
        }

        public int UserID { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Phone { get; set; }
        public virtual string Email { get; set; }

        public virtual ICollection<Quote> Quotes { get; set; }
        public virtual ICollection<Quote> CreatedQuotes { get; set; }
        public virtual ICollection<Quote> ManagedQuotes { get; set; }
        public virtual ICollection<Note> Notes { get; set; }

    }
}

Ответы [ 3 ]

2 голосов
/ 04 октября 2011

Используйте атрибут InverseProperty, чтобы указать другое свойство, участвующее в отношении

public class Quote
{
    public int QuoteID { get; set; }

    public virtual int StateID { get; set; }
    public virtual State State { get; set; }

    public virtual int CreatorID { get; set; }

    [InverseProperty("CreatedQuotes")]
    public virtual User Creator { get; set; }

    public virtual int AgentID { get; set; }
    public virtual User Agent { get; set; }

    public virtual int ManagerID { get; set; }

    [InverseProperty("ManagedQuotes")]
    public virtual User Manager { get; set; }
}

public class User
{
    public User()
    {
        this.Quotes = new HashSet<Quote>();
        this.CreatedQuotes = new HashSet<Quote>();
        this.ManagedQuotes = new HashSet<Quote>();
    }

    public int UserID { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Email { get; set; }

    public virtual ICollection<Quote> Quotes { get; set; }

    [InverseProperty("Creator")]
    public virtual ICollection<Quote> CreatedQuotes { get; set; }

    [InverseProperty("Manager")]
    public virtual ICollection<Quote> ManagedQuotes { get; set; }
    public virtual ICollection<Note> Notes { get; set; }

}

Аналогично сопоставьте другие отношения.

1 голос
/ 04 октября 2011

ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ

Благодаря вашей ссылке на InverseProperty я обнаружил удивительную статью, которая описывает именно то, что я хотел достичь, используя свободный API. Эта статья была написана в январе, но я уверен, что CTP5 теперь официально является частью ядра MVC 3 и EF.

Ассоциации в EF Code First CTP5

Хорошо ... Я собираюсь документировать то, что я нашел, чтобы работать отлично! Я ненавижу, когда люди оставляют частичные ответы, поэтому мы идем.

Здесь есть небольшая избыточность, но она работает. Класс моей цитаты выглядит так:

    [ForeignKey("Creator")]
    public virtual int CreatorID { get; set; }
    [InverseProperty("CreatedQuotes")]
    public virtual User Creator { get; set; }

    [ForeignKey("Agent")]
    public virtual int AgentID { get; set; }
    [InverseProperty("OwnedQuotes")]
    public virtual User Agent { get; set; }

    [ForeignKey("Manager")]
    public virtual int ManagerID { get; set; }
    [InverseProperty("ManagedQuotes")]
    public virtual User Manager { get; set; }

Тогда мой класс User выглядит так:

    public virtual ICollection<Quote> CreatedQuotes { get; set; }
    public virtual ICollection<Quote> OwnedQuotes { get; set; }
    public virtual ICollection<Quote> ManagedQuotes { get; set; }

Наконец, мой класс DBContext выглядит следующим образом:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Quote>()
            .HasRequired(a => a.Manager)
            .WithMany()
            .HasForeignKey(u => u.ManagerID);

        modelBuilder.Entity<Quote>()
                    .HasRequired(a => a.Agent)
                    .WithMany()
                    .HasForeignKey(u => u.AgentID).WillCascadeOnDelete(false);

        modelBuilder.Entity<Quote>()
                    .HasRequired(a => a.Manager)
                    .WithMany()
                    .HasForeignKey(u => u.ManagerID).WillCascadeOnDelete(false);
    }

Вы можете видеть избыточность в аннотации ForeignKey в классе Quote и в отображении Fluent API в классе DbContext, но это ничего не меняет. Я, вероятно, мог бы покончить с аннотациями в классе Quote, но Fluent API необходим, чтобы установить для каскадного правила значение false, чтобы предотвратить конфликты внешних ключей.

Я смог перемещаться в обоих направлениях без проблем и точно так, как ожидалось.

Спасибо за вашу помощь!

1 голос
/ 03 октября 2011

Добавьте атрибут [ForeignKey ("Creator")] в CreatorID и т. Д. Для двух других пар свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...