我有下一个目标:
public class MyEntity
{
public virtual int Id { get; set; }
public virtual MySecondEntity SecondEntity { get; set; }
}
public class MySecondEntity
{
public virtual int Id { get; set; }
...
some properties here
...
}
我不想创建MySecondEntityID属性以获得干净的模型。
我需要通过Id设置myEntity.MySecondEntity,但我不想从DB请求MySecondEntity。
是否可以在不创建MyEntity.MySecondEntityID属性且不加载整个MySecondEntity对象甚至没有任何数据库请求的情况下执行此操作?
答案 0 :(得分:8)
可以手动创建MySecondEntity
对象,并将其作为未更改的对象附加到上下文。
var secondEntity = new MySecondEntity();
secondEntity.Id = id;
context.MySecondEntities.Attach(secondEntity);
entity.SecondEntity = secondEntity;
为了简单起见,我忽略了在上下文中已经存在具有相同键的MySecondEntity
对象的可能性。要做到这一点,您应该检查本地实体(例如通过搜索context.MySecondEntities.Local
)并重新使用实体,如果您在那里找到它。
注意:EF无法知道secondEntity
的其他属性(保留默认值)与数据库中的属性不对应。对于你现在正在做的事情,这没关系,但它可能会在以后的阶段发生。
答案 1 :(得分:2)
对于实体框架5或更高版本,您可以在导航属性旁边添加一个Id,当从db加载实体时,该属性将自动填充。
public class MyEntity
{
public int Id { get; set;}
public int MySecondEntityId { get; set;}
public virtual MySecondEntity MySecondEntity { get; set;}
}
设置MySecondEntityId足以创建关系(保存后)。这样您就不必从db加载实际实体。
如果你有一个可以为空的外键,那么使导航ID可以为空即可。
public int? MySecondEntityId { get; set;}
答案 2 :(得分:2)
使用mutator方法修改ID的受保护属性:
public class MyEntity
{
public virtual int Id { get; set; }
public virtual MySecondEntity SecondEntity { get; set; }
[ForeignKey( "SecondEntity" )]
protected virtual int? MySecondEntityId { get; set; }
public void SetSecondEntityId( int? id )
{
MySecondEntityId = id;
}
}
答案 3 :(得分:0)
如果要在不初始化MyEntity
对象的情况下从数据库中获取MySecondEntity
对象,可以关闭延迟加载。
方法一
Turn of lazy loading on your context.
方法二
从您的实体中删除virtual
关键字:
public class MyEntity
{
public virtual int Id { get; set; }
public MySecondEntity SecondEntity { get; set; }
}
这将禁用SecondEntity
的延迟加载。
More info.