我有一个包含几列的表格,其中一列是“所有者”的FK ID。
在我的删除声明中,我有以下代码:
public ActionResult DeleteEmailTemplate(int id = 0)
{
EmailTemplate EmailTemplate = db.EmailTemplates.Find(id);
Company _Company = SelectCompany();
if (_Company.id != EmailTemplate.CompanyID.id)
return Content("Security Error");
return Content("Passed... Do Delete stuff");
}
这很好,但是,我需要在很多地方这样做,所以我试着提取方法,现在我有:
public ActionResult DeleteEmailTemplate(int id = 0)
{
EmailTemplate EmailTemplate = db.EmailTemplates.Find(id);
if (!SecurityCheck(EmailTemplate.CompanyID.id))
return Content("Security Fail");
return Content("Passed... Do Delete stuff");
}
我认为SecurityCheck
的代码不相关,因为我一直在设置断点,我知道错误是因为调用SecurityCheck
时,EmailTemplate.CompanyID
是空的,但是......我无法理解为什么它是空的。
在第一个示例中,它是Null,但是当我执行SelectCompany()
并检查EmailTemplate
时,EmailTemplate.CompanyID
被设置为正确的值,尽管此方法仅填充{{ 1}}对象,不接触任何其他东西。
在第二个示例中,它再次为Null但保持为null。
所以,问题是我需要帮助:
当数据库具有正确的ID时,我无法弄清楚为什么它是空的。
在运行_Company
之后,我无法弄清楚为什么它在第一个示例中获得了正确的值。
最重要的是,我需要做些什么来解决它?我猜我在某个地方搞砸了,但我只是看不到它。
答案 0 :(得分:1)
我无法弄清楚为什么它是空的 从数据库开始时开始 正确的ID。
这一行...
EmailTemplate EmailTemplate = db.EmailTemplates.Find(id);
...永远不会加载导航属性(在您的情况下为CompanyID
)。导航属性仅加载(使用Include
),显式加载或延迟加载。您似乎没有启用延迟加载,否则访问CompanyID
应该自动加载属性。而且你没有使用其他两个选项。
我无法弄清楚为什么会这样 第一个例子中的正确值 在运行SelectCompany()。
之后
可能是因为关系跨度。当您将公司加载到SelectCompany
方法的上下文中时,Entity Framework会自动修复已加载的其他对象中的引用。因此,EmailTemplate.CompanyID
会自动填充。
最重要的是,我需要什么 要解决它?,
使用上述三个选项之一:
急切加载(一次往返):
EmailTemplate EmailTemplate = db.EmailTemplates.Include(e => e.CompanyID)
.Where(e => e.ID == id).SingleOrDefault();
明确加载(两次往返):
EmailTemplate EmailTemplate = db.EmailTemplates.Find(id);
db.Entry(EmailTemplate).Reference(e => e.CompanyID).Load();
或启用延迟加载。
(在您的特殊情况下,我更喜欢急切加载。)
答案 1 :(得分:0)
SelectCompany
必须运行一些填充CompanyID
的代码。我的猜测是你正在使用延迟加载的ORM而SelectCompany会导致CompanyID被填充。