[英]linq to sql custom method using Expression<Func<…>>
也许我在这个问题上让自己有些困难。 目标是使用一个对象(此处为SearchForm
)来分析数据库记录,并在记录与搜索条目匹配时返回。
由于我的网站允许使用高级搜索表单,因此SearchForm
对象包含很多属性(5个输入字段,一些下拉列表和许多复选框)。 我在用
这是我到目前为止的片段:
public static IEnumerable<CarDetails> SearchByForm(SearchForm form) {
// get db instance
_db = new MyDBDataContext();
var q = from Cars_car c in _db.Cars_cars
join Cars_equipment e in _db.Cars_equipments on c.equipmentId equals e.id
where ValidData.Invoke(c, form)
select new CarDetails {
// filling CarDetails data
};
return q;
}
ValidData
方法是Expression<Func<...>
类型。
private static Expression<Func<Cars_car, SearchForm, bool>> ValidData = (c, f) => MatchesSearchData(f, c);
其中MatchesSearchData
是验证每条记录的方法
private static bool MatchesSearchData(SearchForm f, Cars_car c) {
// long check if true or false and returns it
}
但是有一个错误, the overloaded method has some invalid arguments
在ValidData.Invoke(c, form)
the overloaded method has some invalid arguments
。
我让自己变得困难,还是这是完成我的成果的好方法? 如果是这样,有人可以为我提供上述错误提示的解决方案吗? 如果没有,有些指导用其他方法来解决这个问题?
有一种方法可以使用存储过程执行此操作,但是我更喜欢在此层执行此操作。
二手货源;
编辑1
用户Erti-Chris Eelmaa的回答通过使用Compile()
-method解决了编译器错误。
where ValidData.Compile().Invoke(c, form)
但是在运行时,它会将我重定向到错误页面。 显然,我得到的method has no supported translation to sql
错误。
在控制器中,
public ActionResult Results(SearchForm form) {
ViewBag.cars = Cars_car.SearchByForm(form);
return View("Results");
}
并在模板上(只是快速测试)
@foreach (var car in ViewBag.cars)** {
<p>results : car.Make !</p>
}
**这里,一个method Boolean Invoke(MVCproject2.Models.Cars_car, MVCproject2.Models.SearchForm) has no supported translation to sql
抛出method Boolean Invoke(MVCproject2.Models.Cars_car, MVCproject2.Models.SearchForm) has no supported translation to sql
错误。 这很奇怪,因为添加了Expression方法来为LINQ to SQL提供自定义方法。
或者我错了?
如果希望方法成为SQL查询的一部分,则需要在SQL Server上创建方法,然后调用它。 像这样:
CREATE FUNCTION ReverseCustName(@string varchar(100))
RETURNS varchar(100)
AS
BEGIN
DECLARE @custName varchar(100)
-- Implementation left as exercise for users.
RETURN @custName
END
// and C# part
[Function(Name = "dbo.ReverseCustName", IsComposable = true)]
[return: Parameter(DbType = "VarChar(100)")]
public string ReverseCustName([Parameter(Name = "string",
DbType = "VarChar(100)")] string @string)
{
return ((string)(this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),
@string).ReturnValue));
}
您现在可以在“SQL”查询中使用ReverseCustName(字符串)。
来源: http : //msdn.microsoft.com/en-us/library/vstudio/bb386973(v = vs.100).aspx
或者,您可以将所有内容下载到C#客户端并执行Where
。
public static IEnumerable<CarDetails> SearchByForm(SearchForm form) {
Func<RetailCar_car, SearchForm> compiledLambda = ValidData.Compile();
// get db instance
_db = new MyDBDataContext();
var q = (from Cars_car c in _db.Cars_cars
join Cars_equipment e in _db.Cars_equipments on c.equipmentId equals e.id)
.ToList()
.Where(x => compiledLambda(c, form))
.Select(x => new CarDetails {});
return q;
}
让我们直截了当:当你使用DbContext
,你正在使用IQueryable
。 该类用于生成SQL查询。 如果将C#方法与IQueryable结合使用,LINQSQL不知道如何将其转换为SQL查询。
这两个解决方案对应于:在SQL Server中创建新的SQL方法,或者使用ToList()
将所有内容下载到C#端,这意味着IQueryable
将切换到IEnumerable
。
您能否确认以下LINQ是否正确
var q = from Cars_car c in _db.Cars_cars
join Cars_equipment e in _db.Cars_equipments on c.equipmentId equals e.id
我不明白为什么你在这里使用别名别名。 据我说,这个片段应该是这样的
var q = from c in _db.Cars_cars
join e in _db.Cars_equipments on c.equipmentId equals e.id
可能这不是错误的原因,但我想确认我的理解是否正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.