我尝试执行以下语句:
int count = this.objectReportsRepository.All()
.Count(or => (int)or.GetPropertyValue("ReportingUserId") == reportModel.ReportingUserId
&& or.GetPropertyValue("Reported" + target + "Id") == reportModel.GetPropertyValue("Reported" + target + "Id")
&& DbFunctions.TruncateTime((DateTime)or.GetPropertyValue("ReportDate")) == serverTimeToday);
然而,我收到一个错误: System.NotSupportedException:LINQ to Entities无法识别方法' System.Object GetPropertyValue [QuestionReport](InterpretumDAL.QuestionReport,System.String)'方法,此方法无法转换为商店表达式。
GetPropertyValue 实际上是我自己编写的使用反射的扩展方法:
public static object GetPropertyValue<T>(this T sourceObject, string propertyName)
{
return sourceObject.GetType().GetProperty(propertyName).GetValue(sourceObject, null);
}
我想执行写在我问题顶部的LINQ to Entities语句,因为我有不同的Report实体。例如,我有QuestionReport,UserReport,TagReport等实体。我对他们做了同样的事,但他们有不同的含义。 QuestionReport实体存储Question实体的报告。 UserReport - 用于用户实体等。因此,我想要用户反射,而不是写相同的代码 n 。
我唯一能想到的是在 All()方法调用之后添加 ToList()方法调用,但通过这样做,我实际上加载了所有实体在内存中,只有在此之后我才计算我想要计算的东西,而不是用简单的查询来计算它。
帮助?任何人? :)
答案 0 :(得分:3)
你需要构建表达式树,以便将它用于linq到实体,试试这个表达式。
var or = Expression.Parameter(typeof(ObjectReport));
var cond1 = Expression.Equal(
Expression.Property(or, "ReportingUserId"),
Expression.Constant(reportModel.ReportingUserId));
var cond2 = Expression.Equal(
Expression.Property(or, "Reported" + target + "Id"),
Expression.Constant(reportModel.GetPropertyValue("Reported" + target + "Id")));
var cond3 = Expression.Equal(
Expression.Call(
typeof(DbFunctions),
"TruncateTime",
Type.EmptyTypes,
Expression.Convert(Expression.Property(or, "ReportDate"), typeof(DateTime?))),
Expression.Convert(Expression.Constant(serverTimeToday), typeof(DateTime?)));
var cond = Expression.AndAlso(Expression.AndAlso(cond1, cond2), cond3);
var predicate = Expression.Lambda<Func<ObjectReport, bool>>(cond, or);
int count = this.objectReportsRepository.All().Count(predicate);
答案 1 :(得分:1)
没有冒犯男人,但如果你要滥用这样的仿制品,为什么甚至使用实体框架呢?
您的存储库应该是Repository<T>
,这样当您执行.All()时,您可以直接通过Func选择所需的属性值。然后在您的代码中,只要您需要Repository<QuestionReport>
,一切都会自动设置,您的查询就可以轻松执行
var questions = repository.All(questionReport => questionReport.Question == "How old are you");
你应该从不在任何类型的循环中使用反射。这是非常低效的。
无论如何,如果你仍然设置了这个,你将不得不做.All()。ToList()然后再循环它来做你的逻辑,因为(重写):你正在做非常非常错误。