首先,規格。我們使用MVC5,.NET 4.5.1和Entity framework 6.1。有沒有辦法在lambda表達式樹中使用`dynamic`?
在我們的MVC5商業應用程序中,我們有很多重複的CRUD代碼。我的工作是「自動化」大部分,這意味着將其提取到基類並使其可重用。現在,我擁有控制器,視圖模型和EF6實體模型的基類。
我的抽象基類,所有EF6實體繼承:
public abstract class BaseEntity<TSubclass>
where TSubclass : BaseEntity<TSubclass>
{
public abstract Expression<Func<TSubclass, object>> UpdateCriterion();
}
UpdateCriterion
方法是在數據庫方面的AddOrUpdate
方法使用。我有一個通用的子類參數,因爲UpdateCriterion
需要返回使用確切的子類類型,而不是接口或基類的lambda表達式。以極其簡單的子類實現這個抽象基類是這樣的:
public class Worker : BaseEntity<Worker>
{
public int ID { get; set; }
public int Name { get; set; }
public override Expression<Func<Worker, object>> UpdateCriterion()
{
return worker => worker.ID;
}
}
之後,在我的基本控制器的SaveOrUpdate
行動,我想有這樣的代碼:
public ActionResult Save(TViewModel viewModel)
{
if (ModelState.IsValid)
{
var entityModel = viewModel.ConstructEntityModel();
db.Set<TEntityModel>().AddOrUpdate<TEntityModel>(entityModel.UpdateCriterion(), entityModel);
db.SaveChanges();
}
}
感謝的是,基礎控制器的子類本身不需要像以前那樣實現Save
方法。現在,所有這些工作,儘管時髦的語法,它實際上工作得很好(我的意思是,class BaseEntity<TSubclass> where TSubclass : BaseEntity<TSubclass>
,認真?)。
這是我的問題。對於大多數實體字段ID
是關鍵,但對於一些它不是,所以我無法用超類實現正確地概括。所以現在,每個實體子類實現它自己的UpdateCriterion
。但是,因爲對於大多數(90%以上)實體來說e => e.ID
是正確的實現,所以我有很多重複。所以我想給實體基類改寫爲這樣的:
public abstract class BaseEntity<TSubclass>
where TSubclass : BaseEntity<TSubclass>
{
public virtual Expression<Func<TSubclass, object>> UpdateCriterion()
{
return entity => ((dynamic)entity).ID;
}
}
的目的是提供使用ID爲重點的默認實現,並允許如果他們使用不同的密鑰子類來覆蓋它。我不能使用具有ID字段的接口或基類,因爲並非所有實體都擁有它。我以爲我會用dynamic
拉出ID
字段,但我得到以下錯誤:Error: An expression tree may not contain a dynamic operation
。
那麼,有關如何做到這一點的任何想法?反射在基地UpdateCriterion
工作?
謝謝,這正是我需要的! – Davor
哦,另外,你知道如何在身體部分添加多個字段嗎?像'e => new {e.ID,e.Name}'? – Davor
你知道如何用Expression類創建'e => new {e.ID,e.Name}?'嗎? – codeworx