私はLinqをSQLに使用しており、新しいプロジェクトにEntity Frameworkを使用し始めました。私はVisual Studioに組み込む前にLinqPadを使って自分のコードをテストします。 VSでデバッグしている間、私のカウントに違いがあることに気付きました。 VSで自分のコードで作成したSQLを調べると、正しく翻訳されていないことに気付きました。エンティティフレームワークでC#がSQLに正しく変換されない
VSでの私のコード:
var adviceLineCallTotalViewModelList =
from a in db.AdviceLineCalls
.Include(a => a.Agency)
.Include(a => a.Staff)
.Include(a => a.StatusOfAdviceLineCaller)
.Include(a => a.AdviceLineCallSubjectMatter)
join ag in db.Agencies on a.AgencyNumber equals ag.AgencyNumber
join st in db.StatusOfAdviceLineCallers on a.StatusOfAdviceLineCallerID
equals st.StatusOfAdviceLineCallerID
join s in db.Staffs on a.StaffID equals s.StaffID
join sm in db.AdviceLineCallSubjectMatters on a.AdviceLineCallSubjectMatterID
equals sm.AdviceLineCallSubjectMatterID into grp
from sm in grp.DefaultIfEmpty()
where s.Employed == true
select new AdviceLineCallTotalViewModel()
{
AdviceLineCallID = a.AdviceLineCallID,
AdviceLineCallSubjectMatterID = sm.AdviceLineCallSubjectMatterID,
AdviceLineCallSubjectMatterDesc = sm.AdviceLineCallSubjectMatterDesc,
StatusOfAdviceLineCallerID = st.StatusOfAdviceLineCallerID,
StatusOfAdviceLineCallerDesc = st.StatusOfAdviceLineCallerDesc,
AgencyNumber = a.AgencyNumber,
AgencyNumberNameFacility = ag.AgencyNumberNameFacility,
CallDate = a.CallDate,
CallLength = a.CallLength,
Comments = a.Comments,
StaffID = a.StaffID,
LastName = s.LastName
};
私はデバッグし、生成されたSQLを見て、私は次を参照してください。
SELECT
[Extent1].[AdviceLineCallID] AS [AdviceLineCallID],
[Extent5].[AdviceLineCallSubjectMatterID] AS [AdviceLineCallSubjectMatterID],
[Extent5].[AdviceLineCallSubjectMatterDesc] AS [AdviceLineCallSubjectMatterDesc],
[Extent3].[StatusOfAdviceLineCallerID] AS [StatusOfAdviceLineCallerID],
[Extent3].[StatusOfAdviceLineCallerDesc] AS [StatusOfAdviceLineCallerDesc],
[Extent1].[AgencyNumber] AS [AgencyNumber],
[Extent2].[AgencyNumberNameFacility] AS [AgencyNumberNameFacility],
[Extent1].[CallDate] AS [CallDate],
[Extent1].[CallLength] AS [CallLength],
[Extent1].[Comments] AS [Comments],
[Extent1].[StaffID] AS [StaffID],
[Extent4].[LastName] AS [LastName]
FROM [dbo].[AdviceLineCall] AS [Extent1]
INNER JOIN [dbo].[Agency] AS [Extent2] ON [Extent1].[AgencyNumber] = [Extent2].[AgencyNumber]
INNER JOIN [dbo].[StatusOfAdviceLineCaller] AS [Extent3] ON [Extent1].[StatusOfAdviceLineCallerID] = [Extent3].[StatusOfAdviceLineCallerID]
INNER JOIN [dbo].[Staff] AS [Extent4] ON [Extent1].[StaffID] = [Extent4].[StaffID]
INNER JOIN [dbo].[AdviceLineCallSubjectMatter] AS [Extent5] ON [Extent1].[AdviceLineCallSubjectMatterID] = [Extent5].[AdviceLineCallSubjectMatterID]
WHERE 1 = [Extent4].[Employed]
最後の "INNER JOINを" "LEFT OUTER JOINの" あるべき次の行のために:
join sm in db.AdviceLineCallSubjectMatters on a.AdviceLineCallSubjectMatterID equals sm.AdviceLineCallSubjectMatterID into grp
from sm in grp.DefaultIfEmpty()
右
注:「LEFT OUTER JOIN」が含まれていない理由についての別の記事を読んだ後、「Include」ステートメントを含めました。私は "Includes"の有無にかかわらず同じ結果を得ます。
私はこれまで、他の簡単なクエリでDefaultIfEmpty()を使用していましたが、この問題は発生していませんでした。
EF初心者として、私が何か間違っているのか、私のプロジェクトのEFがどうやってどうやって壊れているのか分かりません。私はEF 6.2を使用しています。
EDIT:
私は新しいVisual Studioプロジェクトを作成し、次のコードを使用:
var adviceLineCallTotalViewModelList = from a in db.AdviceLineCalls
join ag in db.Agencies on a.AgencyNumber equals ag.AgencyNumber
join st in db.StatusOfAdviceLineCallers on a.StatusOfAdviceLineCallerID equals st.StatusOfAdviceLineCallerID
join s in db.Staffs on a.StaffID equals s.StaffID
join sm in db.AdviceLineCallSubjectMatters on a.AdviceLineCallSubjectMatterID equals sm.AdviceLineCallSubjectMatterID into grp
from sm_left in grp.DefaultIfEmpty()
where s.Employed == true
select new AdviceLineCallTotalViewModel()
{
AdviceLineCallID = a.AdviceLineCallID,
AdviceLineCallSubjectMatterID = sm_left == null ? 0 : sm_left.AdviceLineCallSubjectMatterID,
AdviceLineCallSubjectMatterDesc = sm_left == null ? String.Empty : sm_left.AdviceLineCallSubjectMatterDesc,
StatusOfAdviceLineCallerID = st.StatusOfAdviceLineCallerID,
StatusOfAdviceLineCallerDesc = st.StatusOfAdviceLineCallerDesc,
AgencyNumber = a.AgencyNumber,
AgencyNumberNameFacility = ag.AgencyNumberNameFacility,
CallDate = a.CallDate,
CallLength = a.CallLength,
Comments = a.Comments,
StaffID = a.StaffID,
LastName = s.LastName
};
これは行(5104)の正しい数を取得します。また、正しく、最後はLEFT OUTERとして参加作成しますが、JOIN:
LEFT OUTER JOIN [dbo].[AdviceLineCallSubjectMatter] AS [Extent5] ON [Extent1].[AdviceLineCallSubjectMatterID] = [Extent5].[AdviceLineCallSubjectMatterID]
しかし、私の現在のプロジェクト内のコードの同じ行は5つのレコードを返し、最後の結合が間違って登録しようINNERに翻訳されています。
現在のプロジェクトでEFなどが壊れていますか? MVCとEFの入門者として、私は何をすべきか分かりません。
'join sm in db.AdviceLineCallSubjectMatters'とgrp.DefaultIfEmpty()のsm from weirdが奇妙に見えます。 2番目の 'sm in'を' sm_left'に変更して、 'AdviceLineCallSubjectMatterID = sm_left == null 'のようなselect参照をintに変更してみてください。 0:sm_left.AdviceLineCallSubjectMatterID' – bradbury9
@ bradbury9あなたが提案した変更を加えました。私はまだ同じカウントを取得します。しかし、私がコメントすると: 'AdviceLineCallSubjectMatterDesc = sm.AdviceLineCallSubjectMatterDesc '、私は正しいカウントを取得します。注:私はスタックオーバーフローの新しさと私はこのコメントの私のコードの前後にバッククイックを正しく使用している "考える"。 「コメントを追加」をクリックすると、コードブロックとして表示されることがあります。 – MikeNaka
私は確かに@ bradbury9が正しいです。結合と開始の両方のタグとして "sm"を使用すべきではありません。 1つを別のものに変更してから、あなたが使用しているタグのみを参照してください。例えば、 "sm"と "smgrp"。また、オブジェクトに割り当てる際にnullプロパティリファレンスを使用します(つまり、 "AdviceLineCallSubjectMatterID = smgrp?.AdviceLineCallSubjectMatterID ?? string.Empty")。 –