我有以下两个模型
[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是我刚添加到db的对象,pl也不是null。
但是当我尝试从控制器运行以下代码时,其中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为null(evPlace)
知道为什么吗?
答案 0 :(得分:2)
问题与主键是否为string
无关。通常,实体框架不会自动加载导航属性。您需要明确指定:
var ev = db.Events.Include(e => e.Place).SingleOrDefault(e => e.ID == 5);
或者:如果您将Place
属性声明为virtual
...
public virtual Place Place { get; set; }
... EF将为此属性启用延迟加载,并在您的代码中访问它时立即从数据库加载Place
。那么你的代码示例就可以了。请注意,延迟加载会导致对数据库的第二次查询/往返,而急切加载(Include
)会在单个查询中加载事件和位置。
有关加载相关实体的更多信息,请here。