也许我在这个问题上让自己有些困难。目标是使用一个对象(此处为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)
。
我让自己变得困难,还是这是完成我的成绩的好方法? 如果是这样,有人可以为我提供上述错误提示的解决方案吗? 如果没有,一些指导用其他方法来解决这个问题?
有一种方法可以使用存储过程执行此操作,是的,但我更喜欢在此层执行此操作。
使用过的来源;
编辑1
用户Erti-Chris Eelmaa的回答使用Compile()
- 方法解决了编译器错误。
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
错误。这很奇怪,因为添加了Expression方法来为LINQ to SQL提供自定义方法。
或者我错了?
答案 0 :(得分:1)
如果希望方法成为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
。
答案 1 :(得分:0)
您能否确认以下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
可能这不是错误的原因,但我想确认我的理解是否正确。