C# LINQ中的动态选择
假设我有一个类PersonSummary,它结合了来自两个数据库表Person和Address(外键为Person)的属性(列),因此PersonSummary有名字、状态和Zip PersonSummary的创建可以在带有 (person,address=>newpersonsummary{person,address}) 我的数据访问层不了解PersonSummary,因此我想在更高的级别添加select子句,只在较低的级别构造from、where等,以便根据不同的标准从Person和Address中选择行,例如,使用GetFemales()或GetPeopleInAState()等方法 有没有关于如何做到这一点的建议?我的数据访问函数是否应该返回表达式,而更高级别的方法是否应该在其中附加Select子句C# LINQ中的动态选择,c#,.net,linq,C#,.net,Linq,假设我有一个类PersonSummary,它结合了来自两个数据库表Person和Address(外键为Person)的属性(列),因此PersonSummary有名字、状态和Zip PersonSummary的创建可以在带有 (person,address=>newpersonsummary{person,address}) 我的数据访问层不了解PersonSummary,因此我想在更高的级别添加select子句,只在较低的级别构造from、where等,以便根据不同的标准从Person和Add
最受欢迎的签名/返回类型。您只需向IQueryable添加扩展即可:
public static IQueryable<Person> Famales(IQueryable<Person> this entry)
{
return entry.Where(p => p.Gender == Gender.Female);
}
public static IQueryable<Person> LivingInState(IQueryable<Person> this entry, State state)
{
return entry.Where(p => p.State == state);
}
public static IQueryable<Person> PeopleWithAddress(IQueryable<Person> this entry)
{
return entry.Where(p => p.Address != null);
}
// Use like this
var marriedFemales = GetPersonsQuery().Females().Where(f => f.IsMarried)
var femaleVictorians = GetPersonsQuery().Females().LivingInState(State.Victoria)
var femaleVictorians = GetPersonsQuery().PeopleWithAddress()
.Females().Where(x => x.IsMarried)
.Select( x => new { x.LastName, x.Address} )
公共静态IQueryable Famales(IQueryable此条目)
{
返回条目。其中(p=>p.Gender==Gender.Female);
}
公共静态IQueryable生存状态(IQueryable此条目,状态)
{
返回条目。其中(p=>p.State==State);
}
公共静态IQueryable PeopleWithAddress(IQueryable此条目)
{
返回条目。其中(p=>p.Address!=null);
}
//像这样使用
var marriedFemales=GetPersonsQuery().Females()。其中(f=>f.IsMarried)
var femalevctorians=GetPersonsQuery().Females().livingstate(State.Victoria)
var femalevctorians=GetPersonsQuery().PeopleWithAddress()
.Females()。其中(x=>x.IsMarried)
.Select(x=>new{x.LastName,x.Address})
当您使用LINQ使用的底层扩展方法时,您几乎可以做任何您想做的事情
所以,只要您的数据层返回IQueryable信息,您可以说
var withSummary = db.GetFemales()
.Select( p => new PersonSummary(p, p.Address) );
如果您使用的是LINQtoSQL或EF,那么所有数据都是通过单个查询检索的。但是,如果您的LINQ提供程序不够先进,您可以尝试
var withSummary = db.GetFemales().AsEnumerable()
.Select( p => new PersonSummary(p, p.Address) );
但这确实需要您以某种方式预加载(或延迟加载)地址。谢谢,这是一个很好的开始。现在我可以进一步拆分GetPersonQuery(),以便在数据层中使用from和join,在业务层中使用select/projection吗?一种方法是在数据层中定义一个PersonalAddress实体,该实体将包含Person和Address,但我希望避免这种情况。例如,编写一个PeopleWithAddresses()方法(我不知道它的返回类型),并使用var marriedFemales=PeopleWithAddresses().Females().Where(f=>f.IsMarried)。选择new{Person.LastName,Address.State}或just。选择Person.age您可以很容易地做到这一点。我将用另一个示例更新答案。