Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ中的动态选择_C#_.net_Linq - Fatal编程技术网

C# LINQ中的动态选择

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

假设我有一个类PersonSummary,它结合了来自两个数据库表Person和Address(外键为Person)的属性(列),因此PersonSummary有名字、状态和Zip

PersonSummary的创建可以在带有 (person,address=>newpersonsummary{person,address})

我的数据访问层不了解PersonSummary,因此我想在更高的级别添加select子句,只在较低的级别构造from、where等,以便根据不同的标准从Person和Address中选择行,例如,使用GetFemales()或GetPeopleInAState()等方法

有没有关于如何做到这一点的建议?我的数据访问函数是否应该返回表达式,而更高级别的方法是否应该在其中附加Select子句


最受欢迎的签名/返回类型。

您只需向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您可以很容易地做到这一点。我将用另一个示例更新答案。