3

Я хотел бы создать расчетные поля только в .net-коде без определения столбцов в sql.Расчетное поле структуры объекта по выражению <Func<T,V>>

Например, в этом классе:

public class Customer 
{ 
    public int Id { get; set; }    
    public string FirstName { get; set; }    
    public string LastName { get; set; }  
    public DateTime BirthDate { get; set; } 
} 

public class Order 
{ 
    public int Id { get; set; }  
    public Customer Customer { get; set; }    
    public int CustomerId { get; set; }  
    public static Expression<Func<Customer, int>> CustomerBirthYear_Exp = a => a.BirthDate.Year;  
    /// Populated by CustomerBirthYear_Exp 
    public int CustomerBirthYear { get; private set; }    
    public static Expression<Func<Customer, string>> CustomerLastName_Exp = a => a.LastName + " " + a.FirstName;  
    /// Populated by CustomerLastName_Exp 
    public string CustomerFullName { get; private set; } 
} 

, когда я запрос для заказа (ctx.Orders.Select (...) ...), таблица Клиент должен быть сдвинуты и CustomerBirthYear и CustomerFullName должны быть заполнены , Эквивалент

 from o in ctx.Orders 
     join a in ctx.Customers on o.CustomerId equals a.Id 
     select new 
       { 
        o.Id, 
        CustomerFullName = a.LastName + " " + a.FirstName, 
        CustomerBirthYear_Exp = a.BirthDate.Year 
       }; 

Есть ли способ достичь этого, определив пользовательское выражение для конкретного элемента? В другом ORM есть способ объявить об этом: Регистрация (член System.Reflection.MemberInfo, System.Linq.Expressions.LambdaExpression substitution) Заменяет замену в качестве замены для члена.

ответ

1

Нет, в настоящее время это невозможно. Самое близкое, что я видел, это использовать LinqKit для создания многоразовых «селекторов», которые слишком длинные/общие для повторения кода. Он выглядит следующим образом:

var fullNameSelector = MyExpressions.FullNameSelector; 
var query = from o in ctx.Orders.AsExpandable() 
      select new 
      { 
       Id = o.Id, 
       FullName = fullNameSelector.Invoke(o) 
      };