LINQ to entities支持匿名类型作为返回类型,例如:
class TeacherSignupView(View):
def get_context_data(self):
return {'user_form': self.user_form_class, 'teacher_form': self.teacher_form_class}
def get(self, request, *args, **kwargs):
return render(request, 'form.html', self.get_context_data())
def post(self, request, *args, **kwargs):
user_data = {
'some-user-field': request.POST.get('some-user-field')
}
teacher_data = {
'some-teacher-field': request.POST.get('some-teacher-field')
}
# Handle each set of form data individually
user_form = self.user_form_class(user_data)
# Check valid
if user_form.is_valid():
user = user_form.save()
# If user form is valid and user data is saved, then proceed with teacher data
teacher_data["user"] = user # add the user relation here
teacher_form = self.teacher_form_class(teacher_data)
if teacher_form.is_valid():
teacher_form.save()
return render_to_response('index.html', self.get_context_data())
和编译器生成的代码类似于:
var query = from a in b.C select new { Value = a.Value };
但是如果我使用生成的匿名类型实例:
private class f__AnonymousType0<j__TPar>
{
private readonly j__TPar i__Field;
public j__TPar Value
{
get { return i__Field; }
}
public f__AnonymousType0(j__TPar Value)
{
i__Field = Value;
}
}
错误:
var query = from a in b.C select new f__AnonymousType0<string>(a.Value);
将被抛出。
那么匿名类型如何在这里工作?
答案 0 :(得分:5)
如果编译器必须执行一个匿名类型的初始化器,那么它最终会调用构造函数。但是在LINQ to Entities - 或任何其他基于IQueryable
的LINQ提供程序中 - 代码实际上并未执行......它只是转换为表达式树。
所以在你的样本中:
var query = from a in b.C select new { Value = a.Value };
...将转换为对Expression.New
的调用,它有效地表示匿名类型初始值设定项。至关重要(我相信),它会创建一个NewExpression
,并设置Members
属性,以指示Value
属性已从构造函数的第一个参数初始化。
我希望LINQ to Entities分析NewExpression
以找出原始代码的含义,并推断将其转换为SQL需要做什么。它只能通过构造函数调用来实现。