简体   繁体   English

Linq c# - 加入多个条件错误

[英]Linq c# - Join Multiple Conditions Error

I'm trying to make a query with a 3 conditions on a join. 我正在尝试使用连接上的3个条件进行查询。 But I get an error. 但是我收到了一个错误。 In the sql server it's working perfectly, but when I try to convert it to linq it's giving me an erro. sql server它运行得很好,但是当我尝试将它转换为linq它给了我一个错误。

You can take a look below the error and the query. 您可以查看错误和查询下方。

Query: 查询:

var temp = _context
                   .FavouriteVol
                   .Join(_context.Favourites,
                            fv => new { fv.EntityId, fv.CountryId, fv.EType },
                            f => new { f.EntityId, f.CountryId, f.EType },
                                (fv, f) => new { Favourites = f, FavouriteVol = fv })
                                .Where(u => u.Favourites.userId == userId)
                                .Select(f => f.Favourites)
                                .ToList();

Note: EntityId (int), CountryId (string), and EType (int)`. 注意: EntityId (int), CountryId (string)和EType (int)`。 The problem is with the string. 问题在于字符串。 but I need filter also with the string, so any idea how can I do it. 但我也需要过滤字符串,所以任何想法我怎么能这样做。

Error: 错误:

The type arguments for method 'System.Linq.Queryable.Join(System.Linq.IQueryable, System.Collections.Generic.IEnumerable, System.Linq.Expressions.Expression>, System.Linq.Expressions.Expression>, System.Linq.Expressions.Expression>)' cannot be inferred from the usage. 方法'System.Linq.Queryable.Join(System.Linq.IQueryable,System.Collections.Generic.IEnumerable,System.Linq.Expressions.Expression>,System.Linq.Expressions.Expression>,System.Linq)的类型参数。 Expressions.Expression>)'无法从用法中推断出来。

Sql: SQL:

SELECT *
FROM db.FavouriteVol FV
INNER JOIN db.Favourite F On F.EType = FV.EType and F.CountryId = FV.CountryId and F.EType = FV.EType
WHERE F.userId = 5

Any idea how can I fix this problem? 知道如何解决这个问题?

Thanks!! 谢谢!!

Although it's not clear to me why the join including CountryId causes this error, you can work around the problem by matching the CountryId s separately: 虽然我不清楚为什么包含CountryId的连接会导致此错误,但您可以通过单独匹配CountryId来解决此问题:

var temp = _context
           .FavouriteVol
           .Join(_context.Favourites,
                    fv => new { fv.EntityId, fv.EType },
                    f => new { f.EntityId, f.EType },
                        (fv, f) => new { Favourites = f, FavouriteVol = fv })
                        .Where(u => u.Favourites.userId == userId
                                 && u.Favourites.CountryId == u.FavouriteVol.CountryId)
                        .Select(f => f.Favourites)
                        .ToList();

It seems your selector in your Join clause is the problem. 看来您的Join子句中的选择器是问题所在。

.Join(_context.Favourites,
       fv => new { fv.EntityId, fv.CountryId, fv.EType },
       f => new { f.EntityId, f.CountryId, f.EType },
       (fv, f) => new { Favourites = f, FavouriteVol = fv }
)

In LinqToObjects, that expression will work fine but it is invalid in LinqToEntities. 在LinqToObjects中,该表达式可以正常工作但在LinqToEntities中无效。

You have two options. 你有两个选择。

You can either Mark the return sets as Enumerable, in which case all Entities from the sets will be returned to the client and filtered there (not good for performance). 您可以将返回集标记为Enumerable,在这种情况下,集合中的所有实体都将返回到客户端并在那里进行过滤(不利于性能)。
You will get back an anonymously typed object that contains two properties (the entities you're interested in). 您将获得一个匿名类型的对象,其中包含两个属性(您感兴趣的实体)。

Note: I have reworked the queries somewhat. 注意:我在某种程度上重新设计了查询。 I noticed you are testing for whether Favourites == null. 我注意到你正在测试是否收藏夹== null。 That is already taken care of for you with a Join which maps to SQL's INNER JOIN. 这已经为您提供了一个映射到SQL的INNER JOIN的Join。

var temp = _context
             .FavouriteVol
             .AsEnumerable()
             .Join(
                _context.Favourites
                      .Where(u => u.userId == userId)
                      .AsEnumerable(),
                fv => new { fv.EntityId, fv.CountryId, fv.EType },
                f => new { f.EntityId, f.CountryId, f.EType },
                (fv, f) => new { FavouriteVol = fv, Favourites = f }
             )
             .ToList();

Or you will have to specify all returned fields explicitly. 或者您必须明确指定所有返回的字段。 For this approach, you will need to either name the properties carefully or just create a DTO (Data Transfer Object) to hold the return values you are interested in. 对于这种方法,您需要仔细命名属性,或者只需创建一个DTO(数据传输对象)来保存您感兴趣的返回值。

var temp = _context
             .FavouriteVol
             .Join(
                _context.Favourites
                      .Where(u => u.userId == userId),
                fv => new { fv.EntityId, fv.CountryId, fv.EType },
                f => new { f.EntityId, f.CountryId, f.EType },
                (fv, f) => new { 
                   EntityId = fv.EntityId, 
                   CountryId = fv.CountryId, 
                   EType = fv.EType, 
                   //<other fv properties>, 
                   UserId = f.UserId, 
                   //<other f properties>  
                }
             )
             .ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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