如何使用 LINQ 和 Entity Framework 根据条件投影属性?

How to project properties depending on conditions with LINQ and Entity Framework?

我想为 LINQ 列表声明 class 属性 的变量。 我在数据库中有大约 100 个属性,我想根据用户的选择更改输出数据。例如,如果用户选择“A”,我想从 EntityFramework.

中获取“A”值

这是我的示例代码:

List<ReadTime> report = bWDiagnosticEntities2.CA190STEST
   .Where(x => (x.Date > StartDate) && (x.Date <= EndDate))
   .Select(x => new ReadTime 
     { 
         Date = x.Date,
         kody5 = x.kodyBledow5NetVarA 
     })
   .OrderBy(x => x.Date)
   .ToList();

我要更改:

kody5 = x.kodyBledow5NetVarA

kody5 = myVariable

其中 myVariable 取决于用户发送的模型。

我认为最简单的方法是拆分查询和投影部分。 查询将由 EF 在数据库端 运行,并检索所有字段。

然后进行投影 in-memory,并根据用户的选择注入 属性(用户需要从列表中选择现有的 属性)。

在 EF 查询中要记住的一件重要事情是,当您调用 ToList() 时,您将执行实际的数据库查询。然后所有进一步的语句将在内存中执行。

// This will perform an EF query, filtered by the where predicate
var reportEntities = yourContext.YourEntityModelDbSet
     // save resources on EF context if you don't need to update entities later
    .AsNoTracking()
    // Filter as much as you can in this predicate, for it will
    // be translated into SQL by EF
    .Where(x => x.Date > StartDate && x.Date <= EndDate)
    // Calling ToList will retrieve all entites matching the where predicate
    // including all their fields (take care of data size)
    .ToList();
    
// Then, use reflection to retrieve the data
// according to user's choice
var userChoice = GetUserInput(); // will return the property name as a string

var report = reportEntities
    .Select(x => new ReadTime 
     { 
         Date = x.Date,
         // Using reflection to get the value of a property
         // Given its name.
         Kody5 = x.GetType().GetProperty(userChoice)?.GetValue(x, null)
     })
     .ToList();

The ?. operator swallows any exception due to a non-existing property choice. It guarantees you won't get a runtime exception, but you'll never know if the property choice is wrong.

如果数据量是一个问题(它可能,因为你告诉你有大约一百个字段),在 ToList() 之前执行第一个 Select(),你将严格投影无论如何,您将需要的字段。