2009-08-07 69 views
0

比方说,我有PersonSummary类,它结合了来自2个数据库表Person和Address(具有Person的外键)的属性(列),因此PersonSummary具有First Name,State和Zip。LINQ中的动态选择

PersonSummary的创建可以在一个SELECT子句与 (人,地址=>新PersonSummary {人,地址})

我的数据访问层没有PersonSummary的知识,所以我想在较高级别添加select子句,并且仅在较低级别构建from,where等,以根据不同标准从Person和Address中选择行,例如有像GetFemales()或GetPeopleInAState()方法。

有关如何做到这一点的任何建议?我的数据访问函数应该返回表达式,而更高级别的方法只需要在Select子句上使用它?

最受赞赏的签名/返回类型。

回答

0

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

所以ALS只要你的数据层返回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)); 

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

1

你可以只添加扩展的IQueryable:

public static IQuearyable<Person> Famales(IQueryable<Person> this entry) 
{ 
    return entry.Where(p => p.Gender == Gender.Female); 
} 

public static IQuearyable<Person> LivingInState(IQueryable<Person> this entry, State state) 
{ 
    return entry.Where(p => p.State == state); 
} 

public static IQuearyable<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}) 
+0

谢谢,那是一个很好的开始。 现在我可以进一步拆分GetPersonQuery(),以便我可以从数据层和业务层中的选择/投影中获取和连接? 一种方法是在数据层中定义PersonAddress实体,该实体将具有Person和Address,但我想避免这种情况。 因此,对于例如写一个PeopleWithAddresses()方法(我不知道它会返回什么类型),并且有 var marriedFemales = PeopleWithAddresses()。Females()。Where(f => f.IsMarried).Select new {Person。 LastName,Address.State)} 或者只是。选择Person.Age – 2009-08-07 03:19:46

+0

您可以轻松地做到这一点。我会用另一个样本更新答案。 – 2009-08-09 23:22:56