String.IsNullOrWhiteSpace in LINQ Expression

前端 未结 5 1576
醉梦人生
醉梦人生 2020-11-28 21:00

I have the following code:

return this.ObjectContext.BranchCostDetails.Where(
    b => b.TarrifId == tariffId && b.Diameter == diameter
        ||         


        
5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-28 21:21

    In this case it is important to distinguish between IQueryable and IEnumerable. In short IQueryable is processed by a LINQ provider to deliver an optimized query. During this transformation not all C# statements are supported, as it either is not possible to translate them to a back-end specific query (e.g. SQL) or because the implementer did not foresee the need for the statement.

    In contrast IEnumerable is executed against the concrete objects and, therefore, will not be transformed. So, it is quite common that constructs, which are useable with IEnumerable, cannot be used with IQueryable and also that IQueryables backed by different LINQ providers do not support the same set of functions.

    However, there are some workarounds (like Phil's answer), which modify the query. Also, as a more general approach it is possible to drop back to an IEnumerable before continuing with the specification of the query. This, however, might have a performance hit - especially when using it on restrictions (e.g. where clauses). In contrast, when dealing with transformations the performance hit is a lot smaller, sometimes even non existent - depending on your query.

    So the above code could also be rewritten like this:

    return this.ObjectContext.BranchCostDetails
        .AsEnumerable()
        .Where(
            b => b.TarrifId == tariffId && b.Diameter == diameter
            || (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
            ||(!b.TarrifId.HasValue) && b.Diameter==diameter
        );
    

    NOTE: Ths code will have an higher performance impact than Phil's answer. However, it shows the principle.

提交回复
热议问题