0

在我的控制器操作中,我试图将新图像添加到数据库中。图像需要与设备相关联,设备与用户相关联。

所以我有我的实体类:

public class Image
{
   public int Id { get; set; }
   public string Url { get; set; }

   [Required]
   public virtual Device { get; set; }
}

public class Device
{
   public int Id { get; set; }
   public string Name { get; set; }

   [Required]
   public virtual User { get; set; }
}

public class User
{
   public int Id { get; set; }
   public string Login{ get; set; }
   public virtual ICollection<Device> Devices { get; set; }

   [Required]
   [DataType(DataType.EmailAddress)]
   public virtual string Email{ get; set; }
}

现在,当我尝试像这样添加新图像时:

var image = new Image(); 
image.Device = Db.DbSet<Device>().Find(1); 
Db.DbSet<Image>().Add(image); 
Db.DbSet<Image>().SaveChanges();

问题是,当我使用它Find来加载现有设备(用户和所有属性设置正确)时,我没有在设备中获得正确填充的用户属性。就像延迟加载不起作用。有一个User对象的实例,但它的 id 设置为 0,并且它的所有其他字段都设置为其默认值。

我将所有导航属性设置为虚拟,延迟加载在我的其他实体上也可以正常工作,所以它绝对没有关闭或其他什么。

有趣的是,当我在添加图像之前更改代码并进行如下比较时,它会加载用户并正常工作:

if (AuthenticationHelper.CurrentUser != image.Device.User)
    return null;

就像它在这一刻设法加载用户一样。如果我们改变这个比较顺序,那么跟随image.Device.User != AuthenticationHelper.CurrentUser它就不再起作用了。

有什么想法吗?

4

3 回答 3

2

我认为延迟加载工作正常。您找到DeviceID 为 1 的 ,然后将其分配给图像而不User访问Device. 如果模型上没有显式的外键UserID属性,则永远不会访问该属性,因此永远不会有值,并插入 null。DeviceUser

尝试将UserID(或者User_ID如果您想保持实体框架的约定)添加到您的Device模型中,您的代码应该可以工作。

于 2013-07-15T14:32:12.000 回答
1

该问题可能是由Device.User在实体默认构造函数中实例化引用导航属性 ( ) 引起的。在加载和保存实体时,它会导致副作用和意外行为。其他例子在这里这里

于 2013-07-16T16:28:33.770 回答
-1

在“延迟加载”方面,实体框架与 LINQ to SQL 或 NHibernate 并不完全相同。在 EF 中,设计决策是确保开发人员准确地知道他们何时访问资源,例如数据库。因此,延迟加载不会启用“自动”数据库重新查询;相反,它提供了资源的“延迟”加载。EF 永远不会在开发人员不知道的情况下在以后启动辅助数据库调用;相反,开发人员应该显式调用该.Load()方法以启动辅助调用,或者通过.Include().

于 2013-07-16T10:51:56.203 回答