如何使用Linq从table1中检索所有列并匹配table2(左外连接)中的列

时间:2015-08-11 10:03:14

标签: c# linq entity-framework-5

我必须从table1中检索所有列并匹配table2中的列。我有一个存储过程:

alter  Procedure [dbo].[usp_Property]
@UserId bigint =null
As
Begin
select P.PID, P.PropertyName, P.SBUArea, P.ListedOn, 
       P.Availability, P.Price,   F.UserID, F.PID as FavProjId  
       from dbo.Property P left outer join dbo.Favorite F
       on (F.PID=P.PID And F.UserID=@UserId)

我想获得同样的Linq查询。到目前为止,我试过像

这样的东西
//User Id comes from session..
//var userId
var result=(from p in Properties
                   join f in Favorites
                   on p.PID equals f.PID into r
                   from r1 in r.DefaultIfEmpty()
                   where r1.UserID==userId
                   select new
                   {
                     p.PID,
                      p.PropertyName,                       
                      p.SBUArea, p.ListedOn,
                      r1.UserId
                   });

任何人都可以纠正我。我想在这里使用左外连接或任何其他替代方法。

3 个答案:

答案 0 :(得分:1)

如果我美化了你的SP代码,我就明白了:

DECLARE @UserId int 
SET @UserId = 12435 

SELECT 
     P.PID
    ,P.PropertyName
    ,P.SBUArea
    ,P.ListedOn 
    ,P.Availability
    ,P.Price
    ,F.UserID
    ,F.PID AS FavProjId  
FROM Property AS P 
LEFT JOIN Favorite AS F
    ON (F.PID=P.PID AND F.UserID = @UserId)

现在我想知道你是否需要SQL的WHERE子句中的UserId,或者真的在连接中。

但无论如何,这里的LINQ等同于SQL:

System.Int64 __UserId = 12435;

var query = (
    from P in Repo.Property
    from F in Repo.Favorite
         .Where(fav=> fav.PID == P.PID && fav.UserID == __UserId)
         .DefaultIfEmpty() // <== makes join left join
    select new
    {
         PID = P.PID
        ,PropertyName = P.PropertyName
        ,SBUArea = P.SBUArea
        ,ListenOn = P.ListedOn 
        ,Availabiity = P.Availability
        ,Price = P.Price
        ,UserId = F.UserID
        ,FavProjId = F.PID 
    }

);

var data = (query).ToList();

答案 1 :(得分:0)

如果要在join之后放置where子句,则可能会得到空引用异常,因为DefaultIfEmpty返回非匹配行的默认值。您可以在加入之前过滤记录,如下所示: -

var result=(from p in Properties
            join f in Favorites.Where(x => x.UserID == userId)
            on p.PID equals f.PID into r
            from r1 in r.DefaultIfEmpty()
            select new
            {
                p.PID,
                p.PropertyName,                       
                p.SBUArea, 
                p.ListedOn,
                r1.UserId
            });

请注意,您需要使用Favorites访问r1的媒体资源。

<强>更新

据我了解,您需要来自Property表的所有记录,并且仅需要来自Favorite表的匹配行。但是您在收藏夹表上有一个过滤器,因此最终数据源会有所不同。让我通过这个例子说清楚我的观点: -

假设您在Property表中有以下数据: -

PID    PropertyName    Availability    Price
 1          aaa            true         20
 2          bbb            false        10
 3          ccc            true         50
 4          ddd            false        80
 5          eee            true         55
 6          fff            false        70
像这样的

Favorite表: -

FID    PID    UserId
 1      4      1001
 2      2      1005
 3      5      1007

让我们说你想要UserId 1005的所有记录,那么结果应该包含从1到6的所有属性ID,即使UserId 1005不匹配财产Id&#39; 4&amp; 2对吗?所以上面的查询是根据这种理解。使用相同的示例和输出检查此Fiddle

答案 2 :(得分:0)

在您的选择中使用匿名对象

var result = from t in table1
             join x in table2
             on t.id equals x.id
             select new { id = t.id, col1 = t.col1, col2 = x.col2 }