动态选择LINQ

时间:2009-08-07 00:56:00

标签: c# .net linq

假设我有类PersonSummary,它结合了来自2个数据库表Person和Address(使用Person的外键)的属性(列),因此PersonSummary具有First Name,State和Zip。

PersonSummary的创建可以在select子句中使用 (person,address => new PersonSummary {person,address})

我的数据访问层不了解PersonSummary,所以我想在更高级别添加select子句,并且只在较低级别构造from,where等,从Person和Address中选择行基于不同的标准,例如有GetFemales()或GetPeopleInAState()等方法。

有关如何执行此操作的任何建议?我的数据访问函数是否应该返回表达式,而更高级别的方法是否只是对它的Select子句进行处理?

签名/回复类型最受赞赏。

2 个答案:

答案 0 :(得分:1)

您只需向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} )

答案 1 :(得分:0)

当你使用LINQ使用的底层扩展方法时,你几乎可以做任何你想做的事情。

因此,只要您的数据层返回IQueryable信息,您可以说

var withSummary = db.GetFemales()
                    .Select( p => new PersonSummary(p, p.Address) );

如果您使用的是LINQ to SQL或EF,则只需一次查询即可检索所有数据。但是,如果您的LINQ提供程序不太先进,可以尝试

var withSummary = db.GetFemales().AsEnumerable()
                    .Select( p => new PersonSummary(p, p.Address) );

但这确实需要你以某种方式预加载(或延迟加载)地址。