实体框架Linq设置对象的属性,而无需SELECT的其他投影

时间:2016-06-13 17:38:19

标签: c# entity-framework linq inheritance select

我正在使用Entity Framework 6实现继承方案。继承仅存在于DTO级别,即我有两个类Bar : FooIQueryable<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}}

接收上述异常,我正在寻找一种方法来完成这项工作或任何其他解决方案,使我不会在第二次投影期间复制所有基类属性。

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

获取