gpt4 book ai didi

c# - 使用 Expression> 的 linq to sql 自定义方法

转载 作者:行者123 更新时间:2023-11-30 17:50:16 25 4
gpt4 key购买 nike

也许我在这个问题上让自己有些为难。目标是使用一个对象(此处为 SearchForm )来分析数据库记录,并在记录与搜索条目匹配时返回。

由于我的网站允许高级搜索表单,SearchForm对象包含很多属性(5 个输入字段、一些下拉列表和很多复选框)。我正在使用

  • C# NET 4.0(由于 Web 主机的原因不更高)
  • LINQ-to-SQL
  • ASP.NET MVC 4

到目前为止,这是我的代码片段:

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 argumentsValidData.Invoke(c, form) .

我是在给自己添麻烦,还是这是实现目标的好方法?如果是这样,有人可以为我提供上述错误提示的解决方案吗?如果没有,是否有使用其他方法解决此问题的指导?

确实有一种方法可以使用存储过程执行此操作,但我更喜欢在这一层执行此操作。

使用过的资源;

编辑 1

用户 Erti-Chris Eelmaa 的回答通过使用 Compile() 解决了编译器错误-方法。

    where ValidData.Compile().Invoke(c, form)

但是在运行时,它会将我重定向到错误页面。显然,我得到了 method has no supported translation to sql错误。

在 Controller 中,

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 提供自定义方法。

还是我错了?

最佳答案

如果您希望方法成为 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(string)。

来源: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

关于c# - 使用 Expression<Func<...>> 的 linq to sql 自定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20920330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com