gpt4 book ai didi

c# - 使用扩展方法在 EF 中投影单个实体

转载 作者:行者123 更新时间:2023-11-30 23:20:52 25 4
gpt4 key购买 nike

我喜欢使用扩展方法将我的实体模型投影到我的 View 模型中。这意味着我不会过度/不足地获取我的模型,它使代码美观且可读。有时投影可能包含嵌套模型是有道理的,我希望在这些子投影上得到重用。

我希望能够执行以下操作:

ctx.People.FiltersAndThings().ToViewModels();//the project my DB Models into view models

实际投影的扩展方法

public static IQueryable<PersonModel> ToViewModels(this IQueryable<Person> entities)
{
return entities.Select(x => new PersonModel {
Me = x.Me.ToViewModel(), //this method cannot be translated into a store expression
Friends = x.Friends.AsQueryable().ToViewModels() //works fine with some magic (tm)
});
}

public static IQueryable<ProfileModel> ToViewModels(this IQueryable<Profile> entities)
{
return entities.Select(x => new ProfileModel { Name = x.Name });
}


public static ProfileModel ToViewModel(this Profile entity)
{
return new ProfileModel { Name = entity.Name };
}

当使用 Queryable(例如 Friends = x.Friends.AsQueryable().ToViewModels())时,我们可以使用一些魔法将其扁平化为一个表达式(参见 https://stackoverflow.com/a/10726256/1070291,由@回答LordTerabyte)但是当我们使用新子句(例如 Me = new ProfileModel { Name = x.Me.Name })进行赋值时,它不是表达式,所以如果我们将其捆绑在扩展方法下(例如 Me = x.Me.ToViewModel()) 我们不能将它扁平化为一个表达式。

在 EF 中,对新对象的赋值是如何工作的?

有没有办法通过扩展方法转换为新对象?

完整的演示代码在这里:https://github.com/lukemcgregor/ExtensionMethodProjection

编辑:

我现在有一篇博文 ( Composable Repositories - Nesting Extensions ) 和 nuget package帮助在 linq 中嵌套扩展方法

最佳答案

看看this answer .它做的事情与您想要的非常相似。基本上,您会将转换定义为表达式树,例如:

public static Expression<Func<Profile, ProfileModel>> ToProfileViewModel()
{
return entity => new ProfileModel { Name = entity.Name };
}

然后调用它(例如 ExpressionsHelper.ToProfileViewModel().AsQuote()(p))。

如果您愿意,可以修改访问者,以使用更好的语法。沿线的东西:

[ReplacementInExpressionTrees(MethodName=nameof(ExpressionsHelper.ToProfileViewModel))]
public static ProfileModel ToViewModel(this Profile profile)
{
// this implementation is only here, so that if you call the method in a non expression tree, it will still work
return ExpressionsHelper.ToProfileViewModel().Compile()(profile); // tip: cache the compiled func!

现在您需要创建一个访问者,它检查所有方法调用,当找到具有此属性的方法时,它会将整个调用更改为 ExpressionsHelper.ToProfileViewModel().AsQuote()(profile)。这是给你的练习:)

关于c# - 使用扩展方法在 EF 中投影单个实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39585427/

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