0

我在从 EF 4.3 Code First 数据库加载实体时遇到问题。我已将我的代码简化为这个工作示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;

namespace CodeFirst {
    class Program {
        static void Main(string[] args) {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
            Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");

            using (Context context = new Context()) { 
                A a = new A { B = new B { Foo = 1 } };
                context.As.Add(a);
                context.SaveChanges();
                Print(context); // B has ID=1, Foo=1
            }

            using (Context context = new Context()) { 
                Print(context); // B is null
            }

            Console.ReadLine();
        }

        public static void Print(Context context) {
            A a = context.As.Single();
            Console.WriteLine("A: ID=" + a.Id);
            if (a.B == null) {
                Console.WriteLine("B: null");
            }
            else { 
                Console.WriteLine("B: ID=" + a.B.Id + ", Foo=" + a.B.Foo);
            }
        }
    }

    class Context : DbContext {
        public DbSet<A> As { get; set; }
    }

    class A {
        public int Id { get; set; }
        public B B { get; set; }
    }

    class B {
        public int Id { get; set; }
        public int Foo { get; set; }
    }
}

输出是:

A: ID=1
B: ID=1, Foo=1
A: ID=1
B: null

在这个示例代码中,由于某种原因,当我检索A一个 newContext时,它的子属性Bnull. 如果我设置断点并在Bis处连接到数据库null,一切看起来都井井有条:

Table: A
--------
Id    B_Id
1     1

Table: B
--------
Id    Foo
1     1

我只是想学习 Code First,所以我在这里可能有一个严重的误解,但这对我来说似乎很奇怪。谁能解释这种行为?

4

3 回答 3

2

到目前为止提供的两个答案都不必要地麻烦。

只需将您的实体类公开并将您的导航属性声明为virtual,EF 将延迟加载它们(即按需)

DbContext您访问导航属性时,必须打开(即未释放)才能使其正常工作。

于 2012-08-23T01:33:25.910 回答
0

你需要包括他们。

你需要做这样的事情:

var aWithNavProperties = As.Where(a=>a.Id==id).Include(a=>a.B).Single();
于 2012-08-22T21:05:20.763 回答
0

默认情况下,实体框架仅在明确告知这样做时才连接表(这就是导航属性通常 mao 到的连接)。您可以使用以下Include()方法:

var a = context.As.Include("B").Single();

您还可以在加载实体本身后加载属性。这是延迟加载模式的一个实现(应该小心处理,它可以是一个真正的 PITA)

var a = context.As.Single();
// some other code
if (!a.BReference.IsLoaded())
    a.BReference.Load();
于 2012-08-22T21:08:52.590 回答