如何使用 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()
,你将严格投影无论如何,您将需要的字段。
我想为 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()
,你将严格投影无论如何,您将需要的字段。