2

ObjectDataSource を使用してビジネス クラスにアクセスし、ユーザーにとって意味のある出力を生成しようとしています。戻り値は、クラスを表します (ソフトウェアではなく、クラスルームと教育のように)。授業の時間を「9:00 AM - 10:00 AM」のように範囲で表示したいと思います。

これは、データをプルするために使用している Linq クエリです。

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   StartDate = p.StartDate.ToShortDateString(),
                                   EndDate = p.EndDate.ToShortDateString(),
                                   TimeOfClass =
                                   p.StartDate.ToShortTimeString() + " - " +
                                                       p.EndDate.ToShortTimeString()
                               }).ToList();

ご覧のとおり、開始日と終了日は異なる日付になる可能性がありますが、開始日と終了日をエンコードしています。

このコードを実行すると、次のようになります。

「式 'p.EndDate.ToShortTimeString()' を SQL に変換できず、ローカル式として扱うことができませんでした。」

私は結果を投影していることを知っていますが、Linq は初めてなので、ToShortTimeString への C# 呼び出しが投影後に発生したと想定していました。探している文字列を取得する方法を教えてくれる人はいますか?

4

2 に答える 2

5

その理由は、クエリが LINQ to SQL で使用されているためです。LINQ to SQL は、クエリを式ツリーとして扱います。一部のメソッド (たとえば、Contains) に対して定義されたマッピングがありますが、実際にはそれらを実行しないため、任意のメソッドでは機能しません。クエリを解析し、S​​QL サーバーに送信します。クエリに相当するものは、データベース サーバー上で SQL ステートメントとして実行され、結果が返されます。問題はToShortTimeString()、LINQ to SQL に同等の SQL 変換がないことです。ここで使用されるトリックは、SQL サーバーからデータをフェッチし、クライアント側でメソッドを呼び出すことです (AsEnumerableこれを行います)。

return classQuery.Select(p => new { p.ClassID, p.Title, p.StartDate, p.EndDate })
   .AsEnumerable()
   .Select(p => new SelectClassData { 
       ClassID = p.ClassID, 
       Title = p.Title, 
       StartDate = p.StartDate.ToShortDateString(), 
       EndDate = p.EndDate.ToShortDateString(), 
       TimeOfClass = p.StartDate.ToShortTimeString() + " - " + p.EndDate.ToShortTimeString() })
   .ToList();
于 2009-01-15T23:24:02.590 に答える
0

Mehrdadの答えがとても好きです。問題を解決するだけでなく、Linq についても教えてくれます。ありがとうございました!

しかし、私はこの問題を解決し続けてきましたが、別のアプローチを思いついたので、この質問に遭遇した他の誰かが検討したい場合に備えて、ここで説明します. 私のLinq to SQLコードは次のようになりました:

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   sDate = p.StartDate,
                                   eDate = p.EndDate
                              }).ToList();

sDate と eDate は文字列ではなく DateTime オブジェクトになっていることに注意してください。「SelectClassData」オブジェクトでは、宣言を変更して、StartDate、EndDate、および TimeOfClass 変数へのアクセスがプロパティ ゲッターを経由するようにしました。

public class SelectClassData
{
    public int ClassID { get; set; }
    public string Title { get; set; }
    public DateTime sDate { get; set; }
    public DateTime eDate { get; set; }
    public string StartDate { get { return GetSDate(); } }
    public string EndDate { get { return GetEDate(); } }
    public string TimeOfClass { get { return GetTimeOfClass(); } }

    protected string GetSDate()
    {
        return sDate.ToShortDateString();
    }

    protected string GetEDate()
    {
        return eDate.ToShortDateString();
    }

    protected string GetTimeOfClass()
    {
        return sDate.ToShortTimeString() + " - " + eDate.ToShortTimeString();
    }
}

つまり、LinqToSql を介して sDate と eDate を設定しますが、ターゲット データ クラスに実装することで、Linq の取得後に "ToShortTimeString" と "ToShortDateString" 変換を行います。

于 2009-01-16T00:00:30.987 に答える