Свойство навигации Null после запроса в CTP4 Code First EF4 Feature - PullRequest
1 голос
/ 11 августа 2010

Я только начал играть с CTP4 и Code-First.У меня есть следующие настройки для возможного сайта знакомств:

public class User
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string LoginName { get; set; }
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Lastname { get; set; }

    public string Street { get; set; }
    [Required]
    public string Zip { get; set; }
    [Required]
    public string City { get; set; }
    [Required]
    public bool Gender { get; set; }
    [Required]
    public int SoughtGender { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public double Latitude { get; set; }
    [Required]
    public double Longitude { get; set; }
}

 public class Vote
{
    [Key]
    public int ID { get; set; }
    [Required]
    public User Voter { get; set; }
    [Required]
    public User TargetUser { get; set; }
    [Required]
    public int Decision { get; set; }
    [Required]
    public DateTime Timestamp { get; set; }
}

 public class MySQLContext : DbContext
{
    public MySQLContext (string constring)
        : base(constring)
    { }

    public DbSet<User> Users { get; set; }
    public DbSet<Vote> Votes { get; set; }

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Vote>().HasRequired(b => b.Voter).WithMany();
        modelBuilder.Entity<Vote>().HasRequired(b => b.TargetUser).WithMany();
        base.OnModelCreating(modelBuilder);

    }
}

Теперь фреймворк делает хорошую работу по созданию БД со всеми подходящими ключами.Теперь я вставил несколько фиктивных данных и запустил следующий запрос:

public override IEnumerable<Domain.Vote> FindVotes(Domain.User user)
    {
        var query = from v in context.Votes where v.Voter.Id == user.Id select v;
        return from v in query.AsEnumerable() select v;
    }

Запрос возвращает правильные объекты голосования, но два свойства пользователя объекта голосования имеют значение Null.Разве среда не должна заполнять эти свойства внешними ключами пользователей, на которые есть ссылка в таблице голосования?

Ответы [ 2 ]

10 голосов
/ 13 августа 2010

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

Customer.Orders.Load();

Хмм, обратная связь не приветствовалась сообществом, и разработчики хотели ленивую загрузку.Для поддержки Lazy Loading EF команда сказала, что вы должны пометить ваше свойство навигации как виртуальное.Поэтому во время выполнения Ef создает прокси-объект, который наследуется от вашей сущности и переопределяет виртуальное свойство.Ниже приведен пример такого кода.

public class Customer
{
   public string Name{get;set;}
   public virtual ICollection<Order> Orders{get;set;}
}

Во время выполнения есть прокси-сервер, который реализует IEntityWithChangeTracker, а конкретный тип коллекции - это коллекция объектов, существующая с версии 1.

public class CustomerProxy:Customer,IEntityWithChangeTracker
{
private ICollection<Order> orders;
   public override ICollection<Order> Orders
   {
        if(orders == null)
       {
           orders = new EntityCollection<Order>();
           orders.Load();
       }
       return orders;
   }
}
2 голосов
/ 11 августа 2010

смените свой класс на следующий

public class Vote {
    [Key]
    public int ID { get; set; }
    [Required]
    public virtual User Voter { get; set; }
    [Required]
    public virtual User TargetUser { get; set; }
    [Required]
    public int Decision { get; set; }
    [Required]
    public DateTime Timestamp { get; set; }
}

Обратите внимание, что я добавил virtual в свойства Voter && TargetUser, и вы должны быть в порядке.

...