gpt4 book ai didi

c# - 检测 LambdaExpression 是否用于对象的属性

转载 作者:行者123 更新时间:2023-11-30 17:51:23 26 4
gpt4 key购买 nike

我正在尝试通过为需要水合的子对象传递表达式来在存储库中实现一种预加载功能。

    Candidate Get(int candidateId, params Expression<Func<Candidate, object>>[] includes);

所以我的服务可以像这样调用:

        candidateRepository.Get(1, p => p.Notes, p => p.Profile, p => p.Application);

其中,Notes、Profile 和 Application 都是 Candidate 的属性。像这样:

    public class Candidate
{
public string Name { get; set; }

public IList<CandidateNote> Notes { get; set; }

public Profile Profile { get; set; }

public Application Application { get; set; }
}

因此,在存储库中,我需要确定一个属性是否已传递到表达式参数中以实际尝试水化它。但我没有看到一种优雅的方式来实现这一点。

    public Candidate Get(int candidateId, params Func<Candidate, object>[] includes)
{
...

if (candidate.Notes property was specified?)
{
candidate.Notes = this.candidateNoteRepository.List(candidateId);
}

return candidate;
}

看起来我可以通过 (includes[0].Body as MemberExpression).Member.Name 从表达式中获取属性名称,但似乎应该有更简单的方法。另外,我不喜欢字符串比较。我真的不想这样做,除非我必须这样做:

        if (includes[0].Body as MemberExpression).Member.Name == "Notes")
{

看起来应该是很简单的东西

        if (includes[0].Is(candidate.Notes) or includes[0](candidate.Notes).Match())
{

万一它出现了,我非常想保留包含表达式的数组,因为虽然我今天在使用 ADO.NET,但我们计划最终采用 Entity Framework 的方式,并且这些表达式将与 Include 方法配合得很好。

        return this.Filter(m => m.Candidates.CandiateId == candidateId)
.Include(includes[0])

最佳答案

您可能不想这样做。它将强制您在编译时指定所有属性值,这既乏味又容易出错,而且可扩展性不强。

相反,您最好从表达式中获取 MemberInfo 对象,然后使用它来获取该成员的值并设置给定对象的该成员的值。

从一个助手开始,按照您展示的模式从表达式中获取 MemberInfo 对象:

public static MemberInfo GetMemberInfo(LambdaExpression expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
return null;
else
return body.Member;
}

然后就可以获取到需要获取的成员对象的集合:

var members = includes.Select(selector => GetMemberInfo(selector))
.Where(member => member != null)
//this validates the member is from the type itself;
//remove if such validation isn't desired
.Intersect(typeof(Candidate).GetMembers());

然后通过查询或您需要执行的任何其他操作来获取所有这些成员的值以实际获取数据。

然后创建新对象并填充每个成员的值:

var newItem = new Candidate();

foreach(var member in members)
{
//Note that GetValueForMember shouldn't be doing a query.
//it should be getting getting the value from the results
member.SetValue(newItem, GetValueForMember(member));
}

关于c# - 检测 LambdaExpression 是否用于对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19638319/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com