因此,我有一个IQueryable扩展,它的功能比该代码块还要多。本质上,我将一堆字符串组合在一起,然后对它们进行包含。我遇到的问题是,Entity Framework Core不支持System.String.Concat,而是在本地执行查询的那部分,这绝对不是我想要的。
这是我用来将这些不同的字符串加在一起的小循环:
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
//call the concat to create the final term to search on
NewArrayExpression arrayExpression = Expression.NewArrayInit(typeof(string), stringExpressionsToConcat);
searchStringExpression = Expression.Call(concatMethod, arrayExpression);
这是在工作的客户端,但是不会为Entity编译为SQL。我在执行以下操作的Order By子句中遇到了相同的问题:
.ThenByDescending(e => string.Concat(e.FirstName, " ", e.LastName))
这显然也没有转换为Entity to SQL,因为这正是我在表达式树中构建的。但是,将其更改为此。...
.ThenByDescending(e => e.FirstName + " " + e.LastName)
是否将Entity转换为SQL。所以我想知道如何创建上面代码中表示的相同表达式,并将其正确发送到SQL。我尝试使用Expression.Add,但表达式构建器中的字符串类型不支持add。这可能吗?或者实体框架中是否有一些额外的代码可以实现?我曾尝试在GitHub上探索源代码,但要确切地找到它的发生位置却有点不知所措。
答案 0 :(得分:3)
啊哈!我想通了!!此表达式树表现出相同的行为,并将数据发送到SQL!
下面的修改代码:
Shader "Custom/HoleMaker" {
Properties{
_Position("Position", Vector) = (0,0,0,0)
_Scale("Scale", Vector) = (1,1,1,0)
_Radius("Radius", Range(0,1)) = 0.01
_Color("Color", Color) = (1,1,1,1)
_CutawayColor("Cutaway Color", Color) = (1,1,1,1)
}
SubShader{
Tags { "RenderType" = "Opaque"}
LOD 200
Cull Front
CGPROGRAMtypes
#pragma surface surf MonoColor fullforwardshadows vertex:vert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
fixed4 _CutawayColor;
float4 _Position;
float4 _Scale;
float _Radius;
struct Input
{
float2 uv_MainTex;
float3 worldPos;
};
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
v.normal *= -1;
}
half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
return _CutawayColor;
}
void surf(Input IN, inout SurfaceOutput o)
{
//spherical clipping
float dist = length(_Scale.xyz * IN.worldPos.xyz - _Position.xyz);
if (dist < _Radius)
clip(-1);
o.Albedo = _CutawayColor.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
从Entity Framework发出2.2中的警告(以及3.1中的错误)到将其转换为下面的SQL代码!
//more than one member has the property, we need to combine them with spaces in between
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
searchStringExpression = stringExpressionsToConcat[0];
for (int i = 1; i < stringExpressionsToConcat.Count; i++)
{
searchStringExpression = Expression.Add(searchStringExpression,
stringExpressionsToConcat[i], typeof(string).GetMethod("Concat", new[] {
typeof(string), typeof(string) }));
}
这正是Entity Framework生成SQL子句的方式,我在我的回答中使用Order By!我不确定原因是什么...但是,如果您要创建自己的表达式树,这些表达式树将字符串添加在一起,那么Entity Framework Core树访问者可以将其转换为sql!
请使用以下答案来指出正确的方向: https://stackoverflow.com/a/3858421/5245385
答案 1 :(得分:-2)
基本上:请等待EfCore支持该功能,或暂时使用Ef classic。
EfCore在LINQ上提供的支持非常有限-感觉就像开发人员从未使用过它,也从未阅读过LINQ的所有内容。这不是解决方法。
在EfCore 2.2中,它正在进行客户端评估-在3.1中已禁用,它会告诉您去编程不同。
如果您愿意,可以在github页面上打开一个问题,然后也许有人会在11月5.0版中选择它。不会的原因是,这有点不可思议,而且它们充满了更常见的问题。