1

我有以下两种型号

[DataContract]
public class Event
{       
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
    public Place Place { get; set; }
}

[DataContract]
public class Place
{
    [Key]
    public string ID { get; set; }
    public string Name { get; set; }
}

和数据上下文类:

public class myDB: DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Place> Places { get; set; }
}

例如,我运行以下代码

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        Foo();
    }

    private void Foo()
    {
        var db = new myDB();

        var place = new Place
                        {
                            ID = "{59E0F90C-03DB-453C-8C9E-4747957ED37E}",
                            Name = "Home",
                        };

        db.Places.Add(place);
        db.SaveChanges();

        var @event = new Event
        {
            Name = "Test",
            Place = place,
            TimeFrame = new TimeFrame() {StartTime = DateTime.Now, EndTime = DateTime.Now }
        };
        db.Events.Add(@event);
        db.SaveChanges();
        var eventIndex = @event.ID;

        var ev = db.Events.Find(@eventIndex);
        var evPlace = ev.Place;

        var pl = db.Places.Find("{59E0F90C-03DB-453C-8C9E-4747957ED37E}");
    }

一切正常,evPlace 是我刚刚添加到数据库的对象,pl 也不为空。

但是当我尝试从控制器运行以下代码时,其中 5 是新事件对象的 ID

var ev = _db.Events.Find(5);
var evPlace = ev.Place;

var pl = _db.Places.Find("{59E0F90C-03DB-453C-8C9E-4747957ED37E}");

pl 和 ev 不为空,但 ev.Place 为空 (evPlace)

知道为什么吗?

4

1 回答 1

2

该问题与主键是否为 astring无关。通常实体框架不会自动加载导航属性。您需要明确指定:

var ev = db.Events.Include(e => e.Place).SingleOrDefault(e => e.ID == 5);

或者:如果您将该Place属性声明为virtual...

public virtual Place Place { get; set; }

...EF 将为此属性启用延迟加载Place,并在您在代码中访问它时立即从数据库加载。您的代码示例将起作用。请注意,延迟加载会导致对数据库的第二次查询/往返,而急切加载 ( Include) 在单个查询中同时加载事件和地点。

更多关于加载相关实体的信息在这里

于 2012-07-21T14:59:37.293 回答