2

这是我第一次使用 Entity Framework 4.3.1 在 C# 中创建项目。我无法从锦标赛表中获取所有数据,确切地说是地址。

首先,这是我的 Code First 代码。当我运行它时,这 2 个表以正确的关系正确创建。我在这些类中定义了更多的列,但对于这个例子,我只展示了一些。

public class EFDbContext : DbContext
{
    public EFDbContext()
        : base("ApplicationServices")
    {
    }

    public DbSet<Tournament> tournaments { get; set; }
    public DbSet<Address> addresses { get; set; }

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

    public class Tournament
    {
        [ScaffoldColumn(false)]
        public int TournamentId { get; set; }


        [Required(ErrorMessage="Tournament name is a required field")]
        public string Name { get; set; }


        [Required(ErrorMessage="Address is a required field")]
        public Address Address { get; set; }
    }

    public class Address
    {   
        [ScaffoldColumn(false)]
        public int AddressId { get; set; }


        [Required(ErrorMessage="Street name is a required field")]
        public string Street { get; set; }


        [Required(ErrorMessage="House number is a required field")]
        public string HouseNo { get; set; }
    }
}

当我插入一个带有地址的新锦标赛并检查数据库是否使用了关系时,我可以看到它有效。锦标赛有一个指向新插入地址的 Address_AddressId 值。但是当我尝试通过这样做来获取信息时:

Tournament tournament = context.tournaments.Find(id);

我调试它,我可以看到来自锦标赛的所有数据都在锦标赛对象中,除了地址。这设置为空,我完全不知道为什么。

你们能帮帮我吗?

在此先感谢,巴特

4

1 回答 1

3

您需要熟悉一下如何使用 Entity Framework 加载相关数据。介绍在这里:http: //blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx这些是您需要知道的有效使用实体框架的基础知识。

您看到的行为是预期的。Tournament.Address当您仅加载父实体TournamentFind在您的示例中)时,实体框架不会自动加载导航属性 - 比如- 。

加载相关数据基本上有三个选项:

  • 急切加载:

    Tournament tournament = context.tournaments
        .Include(t => t.Address) // <- "eager loading"
        .SingleOrDefault(t => t.TournamentId == id);
    

    我们将在一次往返和数据库查询中加载比赛和地址。

  • 延迟加载:将您的导航属性标记为virtual

    public virtual Address Address { get; set; }
    

    当您加载锦标赛时, EF 将动态创建一个代理对象(派生自Tournament),该对象能够在您访问其属性之一时立即加载相关实体:

    Tournament tournament = context.tournaments.Find(id);
    string street = tournament.Address.Street; // second query to DB happens here
    
  • 显式加载:

    Tournament tournament = context.tournaments.Find(id);
    context.Entry(tournament).Reference(t => t.Address).Load();
    // second query to DB happens here
    

    这类似于延迟加载,因为您还需要两次查询和数据库往返,但您可以明确控制何时Address加载。显式加载具有过滤或排序相关数据的选项(在导航集合的情况下),其他两个选项没有。

于 2012-04-29T15:01:22.083 回答