[英]Entity Framework Linq set property of an object without additional projection by SELECT
我正在使用Entity Framework 6實現繼承方案。繼承僅在DTO級別存在,即,我有兩個類Foo
和Bar : Foo
,我有第一個方法選擇一個IQueryable<Foo>
,然后有幾個方法選擇用於特定的繼承類(如Bar)。
通常,我會有類似的代碼
from foo in SelectFoo()
join barAdditionalProps in .....
select new Bar{
Id = foo.Id,
Description = foo.Description,
Baz = barAdditionalProps.Baz}
結果將提供一個不錯的單個SQL查詢。
不幸的是,這意味着必須在第二次投影期間復制foo的所有屬性(第一個投影在SelectFoo
內部)。 在現實生活中,這意味着使用SelectFoo
在每種方法中復制20多個屬性。
我想做這樣的事情(代碼是在LINQPad中編寫的,假設this
== EFContext):
void Main()
{
(from barBase in SelectT<Bar>()
join field in this.Fields on barBase.Id equals field.ProductId
let _1 = barBase.Baz = field.Baz // this part fails with exception
// An expression tree may not contain an assigment operator
select barBase)
.First()
.Dump();
}
public IQueryable<T> SelectT<T>() where T : Foo, new()
{
return this
.Products
.Select(x => new T
{
Id = x.Id,
Description = x.Description
});
}
public class Foo
{
public string Description {get;set;}
public int Id {get;set;}
}
public class Bar : Foo
{
public int Baz {get;set;}
}
收到上述異常后,我正在尋找一種方法來完成這項工作,或尋求任何其他解決方案使我無法在第二次投影時復制所有基類屬性。
由於沒有可用的現有工具來完成這項工作,因此我編寫了自己的庫,該庫使用表達式樹修改自動將子類dto中的基類dto投影到項目中。
現在代替這個
IQueryable<BaseDto> baseQuery = GetBaseQuery();
IQueryable<SubclassDto> query = from baseDto in baseQuery
let moreData = DataContext.vMoreData.FirstOrDefault(x => x.Id == baseDto.Id)
select new SubclassDto()
{
NewProp1 = moreData.Foo,
NewProp2 = moreData.Baz,
OldProp1 = moreData.SomeOverridingData,
OldProp2 = baseDto.OldProp2,
OldProp3 = baseDto.OldProp3,
OldProp4 = baseDto.OldProp4,
//... 20 more projections from BaseDto to SubclassDto
};
我們有這個
IQueryable<BaseDto> baseQuery = GetBaseQuery();
IQueryable<SubclassDto> query = from baseDto in baseQuery
let moreData = DataContext.vMoreData.FirstOrDefault(x => x.Id == baseDto.Id)
select baseDto.AutoProjectInto(() => new SubclassDto()
{
NewProp1 = moreData.Foo,
NewProp2 = moreData.Baz,
OldProp1 = moreData.SomeOverridingData
});
IQueryable<SubclassDto> activateQuery = query.ActivateAutoProjects();
並且不受SubclassDto初始化約束的所有屬性都是從baseDto自動投影的。
可通過Github https://github.com/IKoshelev/Linq.AutoProject和NuGet https://www.nuget.org/packages/Linq.AutoProject獲取庫
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.