重构Linq到SQL的选择表达式

本文关键字:选择 表达式 SQL Linq 重构 | 更新日期: 2023-09-27 18:05:27

我有一个Linq to SQL语句,有一个非常长的选择列表

List<MyClass> myClasses = (from table1 in context.Table1
                          join table2 in context.Table2
                          on table1.Key equals table2.Key
                          join table3 in context.Table3
                          on table1.FK equals table3.Key
                          select new MyClass()
                          {
                            propertyA = table1.Key
                            // plus about 50 other property setters
                          }).Distinct().ToList();

我正试图找出如何重构select new MyClass() {}表达式中的属性设置成更可用/可读的东西。我已经创建了其他类用来映射相同属性的映射,因此我希望能够利用现有的方法。就像

select new MyClass() 
{
    // Existing mapping method
    MapProperties()
}

这可能吗?这样做的原因是我被要求不编写SQL。

重构Linq到SQL的选择表达式

如果您正在从相同的类(Table1, Table2, Table3)创建您的MyClass,您可以创建一个Expression<Func<CustomTable123, MyClass>>为您做翻译。


设置中间容器

public class CustomTable123
{
  public Table1 Table1 { get; set; }
  public Table2 Table2 { get; set; }
  public Table3 Table3 { get; set; }

创建翻译表达式

public static Expression<Func<CustomTable123, MyClass>> TranslateExp = 
  x => new MyClass
  {
    propertyA = x.Table1.Key,
    ...
  } 
}
  

改变你的查询项目到你的新容器

var query = from table1 in context.Table1
            join table2 in context.Table2 on table1.Key equals table2.Key
            join table3 in context.Table3 on table1.FK equals table3.Key
            select new CustomTable123
            {
              Table1 = table1,
              Table2 = table2,
              Table3 = table3
            };

使用表达式执行所有映射

List<MyClass> myClasses = query.Select(CustomTable123.TranslateExp).Distinct().ToList();

能否将table1, table2和table3传递给MyClass构造函数并在那里进行属性设置?如果不能修改MyClass,那么使用工厂模式返回一个新创建的MyClass并设置属性可能是合适的。

List<MyClass> myClasses = (from table1 in context.Table1
                      join table2 in context.Table2
                      on table1.Key equals table2.Key
                      join table3 in context.Table3
                      on table1.FK equals table3.Key
                      select new MyClass(table1, table2, table3)                         
                      ).Distinct().ToList();

List<MyClass> myClasses = (from table1 in context.Table1
                      join table2 in context.Table2
                      on table1.Key equals table2.Key
                      join table3 in context.Table3
                      on table1.FK equals table3.Key
                      select MyFactory.MakeMyClass(table1, table2, table3)                         
                      ).Distinct().ToList();

创建一个构造函数,用于本地化所需的业务逻辑:

public Class MyClass
{
   public MyClass(table1Class  t1Entity, table2Class t2Entity, table3Class t3Entity)
   {
      // Initialize/map the incoming the class instances
      propertyA = t1Entity.Key;
      ...
   }
}

然后Select的投影(这是select所做的,从一种类型投影到另一种)变得更容易阅读/使用

 ...                     
 on table1.FK equals table3.Key
 select new MyClass(table1, table2, table3){}).Distinct().ToList();