簡體   English   中英

在不同命名空間的基類上使用屬性和元數據

[英]use properties and metadata on base class in different namespace

我有一個單獨的 Visual Studio 項目,用於保存我的數據模型 (EF6)。 因此,我的實體位於命名空間Name1 (首先由 EF6 數據庫創建,但在此示例中簡化如下):

namespace Name1
{
   public class Person
   {
      public string FName {get; set;}
      public string LName {get; set;}
   }
}

現在,我創建了一個新的 MVC 5 項目,它引用了數據 Visual Studio 項目,以便我可以訪問實體。 在我的 MVC 項目中,我想向實體添加一些元數據,如下所示:

namespace NameMvc 
{
   [MetadataType(typeof(PersonMetaData))]
   public class Person : Name1.Person
   {
    
   }

   public class PersonMetaData
   {
      [Display(Name = "Firstname")]
      public string FName;
   }
}

在我的控制器中,我想得到所有人,所以我有一個這樣的動作:

using Name1;
using NameMvc;

-- controller class code
public ActionResult Index()
{
   var persons = db.Person.ToList();
   return View(persons);
}
-- controller class code

在我看來,我嘗試通過以下方式訪問它:

@model IEnumerable<NameMvc.Person>

現在,當我運行代碼時,出現錯誤:

傳遞到字典中的模型項的類型為“System.Data.Entity.Infrastructure.DbQuery`1[Name1.Person]”,但此字典需要類型為“System.Collections.Generic.IEnumerable`1[Name”的模型項.MvcPerson]'。

我可能做的動作有些不對勁,因為db.Person來自Name1命名空間。

我想在我的視圖中使用元數據,這樣當我做這樣的事情@Html.DisplayNameFor(model => model.FName) ,它會顯示“名字”。

您在渲染視圖時遇到錯誤,因為您從操作中返回IEnumerable<Name1.Person> ,但您的視圖期待IEnumerable<NameMvc.Person> 當您在視圖中使用強類型模型時,它必須與操作返回的模型相匹配。

此錯誤有兩種可能的解決方案:

  1. 更改您的視圖以使用IEnumerable<Name1.Person>作為其模型,或
  2. 更改您的操作以返回IEnumerable<NameMvc.Person>作為模型。

當您使用MetadataType向模型添加元數據時,最常見的方法是利用原始模型類作為分部類生成的事實。 您為分部類創建另一個“部分”並向其添加MetadataType屬性。

但是,分部類不能跨程序集使用。 因此,這意味着如果您將模型移至其自己的程序集,則無法向 MVC 項目添加分部類以添加元數據。

要解決此問題,您可以執行以下操作之一:

  1. 在模型的程序集中添加元數據。 為此,您在模型的程序集中使用分部類解決方案。 問題在於您現在將視圖邏輯與數據邏輯混合在一起。
  2. 在您的 MVC 項目中創建一個新類,它是您的數據模型的偽副本,用作視圖模型。 您將元數據添加到其中。 您的操作將返回此視圖模型,您的視圖將使用它。 在您的操作中,您將數據從數據模型復制到視圖模型。

我更喜歡選項#2 有幾個原因:

  1. 它解決了您面臨的問題,並且
  2. 數據呈現給用戶的方式通常與我希望它在我的數據庫中呈現的方式不同。 這個映射讓我可以很好地處理這個問題。

選項#2 的缺點是重復復制數據。 但是,您可以使用AutoMapper 之類的工具來簡化數據復制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM