1

次のコードを実行すると、例外が発生しました。

 var fbPost = db.FacebookStatusUpdates
         .Where(f => 
               f.FacebookUpdateTime - f.ClientTime.Offset <= 
               DateTimeOffset.Now.UtcDateTime - ConvertTimeSpan(f.Offset) &&
               f.Status == FacebookNotificationStatus.Active &&
               f.Alarm.User.FbStatus == true).ToList();

例外メッセージ

指定された型メンバー 'オフセット' は、LINQ to Entities ではサポートされていません。初期化子、エンティティ メンバー、およびエンティティ ナビゲーション プロパティのみがサポートされています。

私のモデル:

 public class FacebookStatusUpdate
 {
    public long Id { get; set; }
    public DateTime FacebookUpdateTime { get; set; }
    public string PostId { get; set; }
    public DateTime? FacebookPostTime { get; set; }
    public DateTimeOffset ClientTime { get; set; }
    public int Offset { get; set; }

    public virtual FacebookNotificationStatus Status { get; set; }
    public virtual Alarm Alarm { get; set; }
}

誰か助けてくれませんか?

4

5 に答える 5

6

LINQ to Entities を使用する場合、クエリが TSQL に変換されることを覚えておく必要があります。Offsetカスタム型の場合、EF はそれを SQL に変換する方法を知りません。

もちろん、クエリをLINQ to Objectsに変換できる場合、これを機能させることができます。

 var fbPost = db.FacebookStatusUpdates
     .Where(f => f.Status == FacebookNotificationStatus.Active &&
                 f.Alarm.User.FbStatus == true)
     .AsEnumerable() // convert from L2E to L2O
     .Where(f => f.FacebookUpdateTime - f.ClientTime.Offset <= 
           DateTimeOffset.Now.UtcDateTime - ConvertTimeSpan(f.Offset))
     .ToList();

AsEnumerable()クエリの残りの部分を呼び出した後は、OffsetコードConvertToTimespanを理解する LINQ to Objects です。明確にするために、クエリを正しい方法で具体AsEnumerable()化することはできません-それでも遅延読み込みが発生します。ただし、その後のクエリはクライアント側で行われ、DB とのやり取りはなくなります。AsEnumerable()

L2E を使用する場合は、サポートされているプリミティブ タイプを使用することをお勧めします。

于 2013-11-15T09:46:48.333 に答える
1

a.MyDate.Offset次のコードは、Linq to Entities クエリで置き換えることができます。

SqlFunctions.DatePart("TZoffset", a.MyDate)

これは SqlServer で機能することに注意してください。

于 2015-07-23T21:05:10.550 に答える
1

db.FacebookStatusUpdatesこれは、データが最初にロードされない可能性があるため、Linq で標準の C# メソッドとプロパティをエンティティに直接使用できないという事実に関係していると思われます。別の言い方をすれば、そのプロパティは SQL に変換できません。

私の理解が正しければ、これはあなたに解決策を提供するかもしれません:

var fbPost = db.FacebookStatusUpdates
              .ToList() // <-- Forces evaluation/data retrieval!
              .Where(f => 
                   f.FacebookUpdateTime - f.ClientTime.Offset <= 
                   DateTimeOffset.Now.UtcDateTime - ConvertTimeSpan(f.Offset) &&
                   f.Status == FacebookNotificationStatus.Active &&
                   f.Alarm.User.FbStatus == true).ToList();

これにより、 を呼び出す前にデータがリストにロードされるClientTime.Offsetため、その呼び出しを行うことができます。

ただし、これには、フィルタリングが適用される前にすべてのデータがロードさWhere()れるという代償があります。コンテキストやその他の要件に基づいて、これが受け入れられるかどうか、または他のより良い解決策を探す必要があるかどうかを判断する必要があると思います.

于 2013-11-15T09:44:45.893 に答える
0

クエリを 2 つの部分に分割できます。

var fbPost_DBQuery = db.FacebookStatusUpdates
     .Where(f => f.Status == FacebookNotificationStatus.Active &&
                 f.Alarm.User.FbStatus == true).ToList();

fbPost_MemoryQuery = fbPost_DBQuery
     .Where(f => f.FacebookUpdateTime - f.ClientTime.Offset <= 
           DateTimeOffset.Now.UtcDateTime - ConvertTimeSpan(f.Offset))
     .ToList();

fbPost_DBQuery は、データベースからより多くの情報を照会し、fbPost_MemoryQuery でフィルター処理します。しかし、それはうまくいきます。

于 2014-03-18T02:01:29.823 に答える