[英]LINQ to SQL query in C#
I am a beginner with C# /LINQ query - I have below query.我是 C#/LINQ 查询的初学者 - 我有以下查询。 Right outer join works fine in Simple SQL, however, I am unable to implement this in LINQ, but not getting anywhere.
右外连接在简单 SQL 中工作正常,但是,我无法在 LINQ 中实现这一点,但无处可去。
SELECT bt.PosGUID,s.PosGUID
FROM tblSchedule s right Join tblTrade bt
ON s.PosGUID = bt.PosGUID AND RowType = '4'
SELECT bt.PosGUID,s.PosGUID
FROM tblTrade bt left Join tblSchedule s
ON s.PosGUID = bt.PosGUID AND RowType = '4'
I need to understand what is the best way to the above left outer join, I guess right outer join is not possible, hence converted to left join and trying to implement.我需要了解上述左外连接的最佳方法是什么,我猜右外连接是不可能的,因此转换为左连接并尝试实现。
Something like - seems to be bit complex query :类似于 - 似乎有点复杂的查询:
var tQuery = from bt in m_DataContext.tblTrades
join bPos in m_DataContext.tblBigPositionStatics on
new { bt.PosGUID } equals
new { bPos.PosGUID }
join bo in m_DataContext.tblBigOrders
on new { bt.ClOrdID, bt.PosGUID } equals new { bo.ClOrdID, bo.PosGUID }
join tradingAcc in m_DataContext.tblTradingAccounts
on new { Entity = bPos.PosEntity, Account = bPos.PosAccount } equals
new { tradingAcc.Entity, tradingAcc.Account }
join btRef in m_DataContext.tblTrades.DefaultIfEmpty()
on new { bt.PosGUID, ExecID = bt.ExecRefID } equals new { btRef.PosGUID, btRef.ExecID }
into temp
from btref in temp.DefaultIfEmpty()
join desk in m_DataContext.tblDesks
on bt.PosDeskGUID equals desk.GUID
// JOIN not working not briging back all records from TBLTrades
join ss in m_DataContext.tblSchedules on bt.PosGUID equals ss.PosGUID into temp1
from ss in temp1.DefaultIfEmpty()
where bt.CreateDateTime >= dateToRun.getDate(false)
&& bt.CreateDateTime < dateToRun.getDate(false).AddDays(1)
&& bo.AsOfDateTime.Date == bt.AsOfDateTime.Date
&& bPos.HardDeleteDate == null
&& ss.RowType == "4"
//&& !"1".Equals(bt.ExecTransType)
//&& bt.HasBeenCorrected == false
&& deskGuidList.Contains(desk.GUID)
select new { bt, bo, desk, bPos, tradingAcc, btref,ss };
If you want to do a right outer join of table A and B, simply exchange these tables and you can do a left outer join.如果你想对表 A 和 B 进行右外连接,只需交换这些表,就可以进行左外连接。
A left outer join is a GroupJoin followed by a SelectMany.左外连接是一个 GroupJoin 后跟一个 SelectMany。 In my experience I use the GroupJoin far more often than I use the Left Outer Join.
根据我的经验,我使用 GroupJoin 的频率远远高于使用 Left Outer Join 的频率。 Especially in One-to-many relations.
尤其是在一对多关系中。
For example: Suppose you have a table of Schools and a table of Students.例如:假设您有一张学校表和一张学生表。 Every School has zero or more Students, every Student studies at exactly one School, using foreign key SchoolId: a straightforward one-to-many relation.
每个学校都有零个或多个学生,每个学生都在一个学校学习,使用外键 SchoolId:一个简单的一对多关系。
Give me all Schools with all their Students
给我所有学校和他们所有的学生
var result = dbContext.Schools
.GroupJoin(dbContext.Students, // GroupJoin Schools and Students
school => school.Id, // from every School take the primary key
student => student.SchoolId, // from every Student take the foreign key
(school, studentsOnThisSchool) => new // from every School with all its Students
{ // make one new object
// Select only the School properties I plan to use
Id = schoolId,
Name = school.Name,
OlderStudents = studentsOnThisSchool
.Select(student => new
{
// Select only the Student properties I plan to use:
Id = student.Id,
Name = student.Name,
...
// not needed, I already know the value:
// SchoolId = student.SchoolId,
});
The result will be a sequence like:结果将是一个序列,如:
School 1 with Students A, B, C, D.
School 2 with Students E, F,
School 3 without any Students
School 4 with Students G, H, I,
...
This seems to me much more useful than the result of the left outer join:在我看来,这比左外连接的结果有用得多:
School 1 with Student A,
School 2 with Student E,
School 3 with Null student,
School 1 with Student B,
School 2 with Student F,
School 1 with Student C,
...
But hey, it's your choice.但是,嘿,这是你的选择。
I have a TblTrade, which contains Trades.
我有一个包含交易的 TblTrade。 Every Trade has at least properties Bt, PosGuid and RowType.
每个交易至少有属性 Bt、PosGuid 和 RowType。 I also have a TblSechedule which contains Schedules.
我还有一个包含时间表的 TblSchedule。 Every Schedule has at least properties Bt and PosGuid.
每个 Schedule 至少有属性 Bt 和 PosGuid。 Give me all Trades with RowType 4 with all zero or more Schedules that have the same value for PosGuid.
给我 RowType 4 的所有交易,以及所有零个或多个具有相同 PosGuid 值的计划。
var result = tblTrade
// keep only the trades that have RowType equal to 4:
.Where(trade => trade.RowType == 4)
// do the GroupJoin:
.GroupJoin(tblSchedule,
trade => trade.PosGuid,
schedule => schedule.PosGuid,
(trade, schedulesWithSamePosGuid) => new
{
// Select the trade properties you plan to use:
TradeId = trade.Id,
PosGuid = trade.PosGuid,
...
Schedules = schedulesWithSamePosGuid.Select(schedule => new
{
// Select the schedule properties you plan to use:
Id = schedule.Id,
...
// not needed, you already know the value:
// PosGuid = schedule.PosGuid.
})
.ToList(),
});
If you really want a flat Left Outer Join, add a SelectMany:如果你真的想要一个扁平的左外连接,添加一个 SelectMany:
.SelectMany(groupJoinResult.Schedules,
(trade, schedule) => new
{
PosGuid = trade.PosGuid,
// the Trade properties:
Trade = new
{
Id = trade.TradeId,
...
},
Schedule = new
{
Id = schedule.Id,
...
},
});
If you want, you can create an extension function LeftOuterJoin:如果你愿意,你可以创建一个扩展函数 LeftOuterJoin:
public static class MyQueryableExtensions
{
// version without EqualityComparer:
public static IQueryable<TResult> LeftOuterJoin<T1, T2, TKey, TResult>(
this IQueryable<T1> source1,
IQueryable<T2> source2,
Func<T1, TKey> key1Selector,
Func<T2, TKey> key2Selector,
Func<T1, T2, TResult) resultSelector)
{
return LeftOuterJoin(source1, source2,
key1Selector, key2Selector, resultSelector, null);
}
version with EqualityComparer:带有 EqualityComparer 的版本:
public static IQueryable<TResult> LeftOuterJoin<T1, T2, TKey, TResult>(
this IQueryable<T1> source1,
IQueryable<T2> source2,
Func<T1, TKey> key1Selector,
Func<T2, TKey> key2Selector,
Func<T1, T2, TResult) resultSelector,
IEqualityComparer<TKey> comparer)
{
if (comparer == null) comparer = EqualityComparer<TKey>.Default;
// GroupJoin followed by SelectMany:
return GroupJoin(source1, source2, key1Selector, key2Selector,
(source1Item1, source2ItemsWithSameKey) => new
{
Source1Item = source1Item,
Source2Items = source2ItemsWithSameKey,
})
.SelectMany(groupJoinResult => groupJoinResult.Source2Items,
(groupJoinResult, source2Item) =>
ResultSelector(groupJoinResult.Source1Item, source2Item));
}
}
Usage:用法:
var result = tblTrade
.Where(trade => trade.RowType == 4)
.LeftOuterJoin(tblSchedule,
trade => trade.PosGuid,
schedule => schedule.PosGuid,
(trade, schedule) => new
{
// Select the trade and Schedule properties that you plan to use
// for example the complete trade and schedule:
Trade = trade,
Schedule = schedule,
// or only some properties:
CommonPosGuid = trade.PosGuid,
Trade = new
{
Id = trade.Id,
...
}
Schedule = new
{
Id = trade.Id,
...
}
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.