我正在使用Entity Framework 6实现继承方案。继承仅存在于DTO级别,即我有两个类Bar : Foo
和IQueryable<Foo>
,
我有第一个选择from foo in SelectFoo()
join barAdditionalProps in .....
select new Bar{
Id = foo.Id,
Description = foo.Description,
Baz = barAdditionalProps.Baz}
的方法,然后是几个方法,为Bar等特定的继承类选择其他属性。
通常情况下,我会有像
这样的代码SelectFoo
这将给出一个很好的单个SQL查询。
遗憾的是,这意味着必须在第二次投影期间复制foo的所有属性(第一个属于SelectFoo
内)。在现实生活中的代码中,这意味着使用this
在每种方法中复制了20多个属性。
我想做类似的事情(代码在LINQPad中编写,假设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;}
}
== EFContext):
{{1}}
接收上述异常,我正在寻找一种方法来完成这项工作或任何其他解决方案,使我不会在第二次投影期间复制所有基类属性。
答案 0 :(得分:0)
由于没有现有工具可以完成工作,我编写了自己的库,使用表达式树修改自动将子类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
获取