繁体   English   中英

linq to sql使用Expression自定义方法 <Func<…> &gt;

[英]linq to sql custom method using Expression<Func<…>>

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

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

  • C#NET 4.0(由于网络主机而不是更高)
  • LINQ到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) 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM