C#Linq Guid匿名型の問題
-
05-07-2019 - |
質問
質問テキストに基づいて質問のIDを返すlinqクエリがあります。 このIDは、日付テーブルの日付を特定の質問に関連付けるために使用する必要があります。質問はすでに保存されており、日付は別の時間に保存されています。
問題は、クエリがquestionIDを匿名型として返すため、そのquestionIDを別のテーブルのquestionIDとして割り当てる必要がある場合、テーブルがGuidを予期していることを示すエラーをスローすることです。これに続いて、匿名型を文字列に変換し、GUID変換機能を使用して文字列をGUIDに変換しましたが、GUIDが32文字と4つのダッシュである必要があるというエラーが表示されます。
これに関する私の考えは、匿名型が「QuestionID = jkj939-89239829-etc。」などのquestionIDを返すことです。 -文字のプレフィックスが先頭にあるため、GUIDに変換するとき、変換された文字列にはこれらの文字が含まれます。
何か見逃したことがありますか? 私はそれがなぜこれを行うのか本当に理解できません、匿名型によって返されたプレフィックスを削除する方法はありますか? ヘルプをいただければ幸いです。
コードは次のとおりです:
public static void GetQuesID(string quesText)
{
ExamineDataContext dc = new ExamineDataContext();
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new{
q.QuestionID
};
foreach (var element in matchedques)
{
MessageBox.Show(element.ToString());
}
try
{
Guid g = Guid.NewGuid();
Table<DateLastUsed> dlused = Repository.GetDateLastUsedTable();
DateLastUsed dlu = new DateLastUsed(); ;
string qidGuidString = matchedques.ToString();
Guid convQuesGuid = new Guid(qidGuidString);
dlu.DLUID = g;
dlu.QuestionID = convQuesGuid;
dlu.DateLastUsed1 = DateTime.Now;
dlused.InsertOnSubmit(dlu);
dlused.Context.SubmitChanges();
}
catch (Exception ex)
{
throw ex;
}
}
解決
何かが足りない場合を除き、新しい匿名型ラッパーを作成するのではなく、 q.QuestionID
を選択してください。
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select q.QuestionID;
foreach (var element in matchedques)
{
MessageBox.Show(element.ToString());
}
別の方法として、フィールドに名前(&quot; theID
&quot;)を付けて直接アクセスします:
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new{
theID = q.QuestionID
};
foreach (var element in matchedques)
{
MessageBox.Show(element.theID.ToString());
}
どうやら、私が最初に思った以上の質問がありました。コメントへの回答として、matchedquesの結果の enumeration を返すことに注意してください(したがって、foreachが正しいのですか?)。したがって、次の行にもエラーがあります。
string qidGuidString = matchedques.ToString();
どちらかが欲しい
string qidGuidString = matchedques.Single().ToString();
matchedquesに単一の結果が含まれる場合、matchedquesに複数の結果が含まれる場合はforeachループ。
GUIDを文字列に変換して再び戻す理由はないことに注意してください。クエリを使用して、より有用なもの(つまり、新しい DateLastUsed
オブジェクト)を返すこともできます。
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new DateLastUsed() {
DLUID = Guid.NewGuid(),
QuestionID = q.QuestionID,
DateLastUsed1 = DateTime.Now
};
Table<DateLastUsed> dlused = Repository.GetDateLastUsedTable();
foreach(var dlu in matchedques)
{
dlused.InsertOnSubmit(dlu);
dlused.Context.SubmitChanges();
}
他のヒント
この「select new {q.QuestionID};」ではなく、単に select q.QuestionID;
をしないでください。ものですか?
matchedquesで.ToString()を呼び出しています。これは列挙です:
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new{
q.QuestionID
};
string qidGuidString = matchedques.ToString();
したがって、上記の例では、matchedquesは匿名型の列挙です(おそらくこれを廃止して、q.QuestionIDを直接選択する必要があります)。これでToString()を呼び出すと、単にシーケンスの最初の要素のQuestionIdではなく、オブジェクトの文字列表現が返されます。
上記のクエリの結果が常に1つだけになると予想していますか?もしそうなら、おそらくシングル演算子を見るべきです。
次のようなことが必要です:
var matchedQuesId =
dc.GetTable<Question>()
.Where(q =>q.QuestionText.Contains(quesText))
.Single()
.QuestionID;
この場合、matchedQuesIdを直接使用できます。 Whereクエリがどれにも一致しない場合、または複数の要素に一致する場合、エラーがスローされることに注意してください。 Single演算子を読んで理由を調べてください。
これを試してください:
var matchedques = (from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new{
q.QuestionID
}).FirstOrDefault();
次に、単純に:
if (matchedques != null){
// Just use matchedques.QuestionID to get your value
}
FirstOrDefault
は、 matchedques
変数を、オブジェクトの列挙ではなく、オブジェクトの単一インスタンスに設定します。必要な値が1つだけであることがわかっている場合は、非常に役立ちます。 OrDefault
ビットは、何も見つからなかった場合に NULL
になることを意味します。
変更先:
...
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select q.QuestionID;
e.g。新しい{...}を削除して、idプロパティで新しい匿名型を作成します。