【问题标题】:CodeFirst access property of another virtual propertyCodeFirst 访问另一个虚拟属性的属性
【发布时间】:2015-09-10 10:46:23
【问题描述】:

我在 CodeFirst 脚手架的 ASP.NET MVC 站点中使用了以下模型(简化):

Public Tax
{
   public int ID {get; set; }
   public string Name {get; set; }
   public decimal Rate {get; set; } 
}

Public OrderLine
{
   public int ID {get; set; }

   public int TaxID {get; set; }
   public virtual Tax Tax {get; set; }

   public decimal Quantity {get; set; }
   public decimal Price {get; set; }

   [ScaffoldColumn(false)]
   public decimal Amount
   {
      get { return Quantity * Price; }
      set { }
   }

   [ScaffoldColumn(false)]
   public decimal AmountWithTax
   {
      get { return Amount + (Amount * Tax.Rate / 100); }
      set { }
   }
}

Amount 和 AmountWithTax 是计算属性,我不需要它们在 UI 中,但我需要将它们保存在数据库中。问题是当我创建一个新的OrderLine 属性Tax 为空(TaxID 已填充并包含 int 值)所以AmountWithTax 抛出异常。

如何访问Rate 属性?

重现步骤:

将这两个模型添加到标准的 ASP.NET MVC EF 项目中,使用右键单击创建脚手架项目 -> 添加 > 新建脚手架项目... -> MVC5 ... 使用 EntityFramework -> 并选择模型中的模型类。

Visual Studio 将生成控制器和视图,如果 Create 视图创建了 OrderLine,则会在属性 Tax.Rate 上抛出 NullReferenceException,因为 Tax 为空

【问题讨论】:

  • 显示更多代码。你如何创建一个新的OrderLine?您不应该使用 ViewModel 而不是实体模型吗?如果你不想这样,你不能设置newOrderline.Tax = db.Taxes.Find(newOrderline.TaxID)吗? AmountWithTax什么时候扔?
  • OrderLine 是使用脚手架视图创建的,因此代码是生成的标准代码,并且没有调用 HttpPost 方法 public ActionResult Create 因为之前发生空异常(所以在我点击创建后我获取异常)
  • 请解释在您的问题中重现它的所有相关步骤。包括您的 Create 操作方法代码。还要提及完整的例外情况。
  • 您缺少操作方法。您仍然没有解释异常发生的何时和何处。
  • 异常发生在属性 AmountWithTax 的 get 方法中。我的要求是:创建订单行时,需要使用 Tax 的 Rate 值计算 AmountWithTax,这可以使用 CodeFirst 吗?

标签: c# asp.net-mvc entity-framework


【解决方案1】:

您应该使用 ViewModel,而不是实体模型。使用将您想要的属性映射到实体模型的视图模型应该会为您修复它。

如果您不希望这样,您可以按照How do you exclude properties from binding when calling UpdateModel()? 中的说明将属性排除在绑定之外:

[Bind(Exclude="Amount,AmountWithTax")]

这将使模型绑定器忽略这些属性,导致它们的set 不会被调用。

顺便说一句,Amount 和AmountWithTax 的设置器将导致StackOverflowException,因为它们正在为自己分配一个值。您也可以通过简单地删除 set 将它们设为只读。

【讨论】:

  • 问题是异常是在get内部抛出的,而不是在set上。我更新了我的源代码,对于 Amount 属性,空集给出了预期的结果,但是对于 AmountWithTax,Tax 为空,我不知道我可以在哪里填写它
  • 这就是为什么我现在两次要求您在您的问题中发布完整的异常及其堆栈跟踪。问题不是实体框架,也不是代码优先。
  • 样式public int TaxID {get; set; } public virtual Tax Tax {get; set; }是因为它是在EntityFramework CodeFirst中使用的1:N关系,我可以为Tax选择一个值但是有一种方法可以使用Tax对象的属性吗?
  • 我在first comment to your question 中解释了如何做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多