具有复杂类型的EF4.1模型,主键为字符串不能正常工作

时间:2012-07-21 14:52:59

标签: c# asp.net entity-framework

我有以下两个模型

[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)

知道为什么吗?

1 个答案:

答案 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