C# 如何使用反射重写此LINQ查询
所以我使用反射编写了这个LINQ查询,后来发现它不受支持。从这段代码中获得相同功能的最佳方法是什么C# 如何使用反射重写此LINQ查询,c#,linq,dynamic,reflection,C#,Linq,Dynamic,Reflection,所以我使用反射编写了这个LINQ查询,后来发现它不受支持。从这段代码中获得相同功能的最佳方法是什么 List<Profile> profilesFromUUID = await MobileService.GetTable<Profile>().Where(p => typeof(Profile) .GetProperty(handler.Name + "UUID").GetValue(p) == obj.uuid).ToListAsync(); List pro
List<Profile> profilesFromUUID = await MobileService.GetTable<Profile>().Where(p => typeof(Profile)
.GetProperty(handler.Name + "UUID").GetValue(p) == obj.uuid).ToListAsync();
List profilesFromUUID=wait mobileseservice.GetTable()。其中(p=>typeof(Profile)
.GetProperty(handler.Name+“UUID”).GetValue(p)=obj.UUID.toListSync();
比较一下所有的属性名怎么样?根据定义,UUID无论如何都不会有冲突。由于Profile
只是一个数据类,因此UUID属性的#是固定的
List<Profile> profilesFromUUID = await MobileService.GetTable<Profile>()
.Where(p =>
p.A_UUID == obj.uuid ||
p.B_UUID == obj.uuid ||
p.C_UUID == obj.uuid)
.ToListAsync();
List profilesFromUUID=wait mobileseservice.GetTable()
.其中(p=>
p、 A_UUID==obj.UUID |
p、 B_UUID==obj.UUID||
p、 C_UUID==obj.UUID)
.ToListAsync();
或为配置文件添加方法(扩展方法),如:
public static Guid GetUUIDByTableName(this Profile value, string tableName)
{
switch (tableName)
{
case "A_": return value.A_UUID;
case "B_": return value.B_UUID;
default: return Guid.Empty;
}
}
List<Profile> profilesFromUUID = await MobileService.GetTable<Profile>()
.Where(p => p.GetUUIDByTableName(handler.Name) == obj.uuid)
.ToListAsync();
公共静态Guid GetUUIByTableName(此配置文件值,字符串tableName)
{
开关(表名)
{
案例“A_UUID”:返回值.A_UUID;
案例“B_UUID”:返回值.B_Uid;
默认值:返回Guid.Empty;
}
}
List profilesFromUUID=await MobileService.GetTable()
.Where(p=>p.getUUIByTableName(handler.Name)==obj.uuid)
.ToListAsync();
使用反射创建查询,而不是在查询中。考虑:
public static IQueryable<Profile> Filter(
this IQueryable<Profile> source, string name, Guid uuid)
{
// .<name>UUID
var property = typeof(Profile).GetProperty(name + "UUID");
// p
var parExp = Expression.Parameter(typeof(Profile));
// p.<name>UUID
var methodExp = Expression.Property(parExp, property);
// uuid
var constExp = Expression.Constant(uuid, typeof(Guid));
// p.<name>UUID == uuid
var binExp = Expression.Equal(methodExp, constExp);
// p => p.<name>UUID == uuid
var lambda = Expression.Lambda<Func<Profile, bool>>(binExp, parExp);
// source.Where(p => p.<name>UUID == uuid)
return source.Where(lambda);
}
返回一个IQueryable
,其中附加了相应的。因此:
var profilesFromUUID = await MobileService.GetTable<Profile>().Filter(handler.Name, obj.uuid).ToListAsync();
相当于:
from p in MobileService.GetTable<Profile>() where p.AUUID = uuid0 && p.BUUID == uuid1
from p in MobileService.GetTable<Profile>() where p.AUUID = uuid0 || p.BUUID == uuid1
来自MobileService.GetTable()中的p,其中p.AUUID=uuid0&&p.BUUID==uuid1
以及:
MobileService.GetTable().Filter(“A”,uuid0).Union(
MobileService.GetTable().Filter(“B”,uuid1))
相当于:
from p in MobileService.GetTable<Profile>() where p.AUUID = uuid0 && p.BUUID == uuid1
from p in MobileService.GetTable<Profile>() where p.AUUID = uuid0 || p.BUUID == uuid1
MobileService.GetTable()中p的,其中p.AUUID=uuid0 | | p.BUUID==uuid1
更普遍的版本是:
public static IQueryable<TSource> FilterByNamedProperty<TSource, TValue>(this IQueryable<TSource> source, string propertyName, TValue value)
{
var property = typeof(TSource).GetProperty(propertyName);
var parExp = Expression.Parameter(typeof(TSource));
var methodExp = Expression.Property(parExp, property);
var constExp = Expression.Constant(value, typeof(TValue));
var binExp = Expression.Equal(methodExp, constExp);
var lambda = Expression.Lambda<Func<TSource, bool>>(binExp, parExp);
return source.Where(lambda);
}
公共静态IQueryable筛选器ByNamedProperty(此IQueryable源、字符串属性名称、TValue值)
{
var property=typeof(TSource).GetProperty(propertyName);
var parExp=Expression.Parameter(typeof(TSource));
var methodExp=Expression.Property(parExp,Property);
var constExp=表达式常数(值,类型(TValue));
var binExp=Expression.Equal(methodExp,constExp);
var lambda=Expression.lambda(binExp,parExp);
返回源。其中(λ);
}
然后,当您必须在调用代码中执行+“UUID”
时,您可以使用它对任何元素类型的任何IQueryable
执行类似查询。这当然是一种方法。然而问题是Profile表有很多其他表的外键,所有这些表都有自己的uuid。因此,我需要找到与ForeignKeyTableName+uuid
字符串匹配的特定uuid。我想有更好的方法,因为我知道我正在查找的uuid的字符串值for@DillonDrobena我认为添加条件(handler.Name==“A_u”&&p.A_UUID==obj.UUID)
对性能没有多大帮助。。UID的比较应该足够好了。我想说的是handler。Name包含了我需要立即找到属性的信息。因此,例如(使用反射)handler.Name=TableA
,通过使用反射,我可以立即获得我要查找的属性,而不必查看obj.uuid==TableA.uuid | | obj.uuid==TableB.uuid | |……|TableZ.uuid=obj.uuid
如果我找不到在查询中使用反射的方法,我将使用您的建议。您需要添加代码以允许getuuidytablename
作为SQL执行,否则它与查询提供程序的协同工作将与问题中的原始代码相同。如果也许您获取了一个IQueryable
,在开关中应用了Where
,然后返回了生成的IQueryable
。我将如何使用var profilesFromUUID=wait MobileService.GetTable().Filter(handler.Name,obj.uuid).ToListAsync()
因为过滤器
不是方法派生的MobileService.GetTable()
?哦,我想它需要像扩展一样使用?是的,因此方法签名中的这个
。将其作为扩展使其类似于Where
,实际上,这使我想到了一个更通用的版本。
public static IQueryable<TSource> FilterByNamedProperty<TSource, TValue>(this IQueryable<TSource> source, string propertyName, TValue value)
{
var property = typeof(TSource).GetProperty(propertyName);
var parExp = Expression.Parameter(typeof(TSource));
var methodExp = Expression.Property(parExp, property);
var constExp = Expression.Constant(value, typeof(TValue));
var binExp = Expression.Equal(methodExp, constExp);
var lambda = Expression.Lambda<Func<TSource, bool>>(binExp, parExp);
return source.Where(lambda);
}