web-dev-qa-db-ja.com

EFでDateTimeの日付コンポーネントのみを比較するにはどうすればよいですか?

2つの日付値があります。1つは既にデータベースに格納されており、もう1つはDatePickerを使用してユーザーが選択します。ユースケースは、データベースから特定の日付を検索することです。

以前にデータベースに入力された値は、常に12:00:00の時間コンポーネントを持ちます。ピッカーから入力された日付は異なる時間コンポーネントを持っています。

日付コンポーネントのみに興味があり、時間コンポーネントは無視したいです。

C#でこの比較を行う方法は何ですか?

また、LINQでこれを行う方法は?

更新:LINQ to Entitiesでは、以下が正常に機能します。

e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0
114
pencilslate

注:この回答を書いた時点では、EF関係は不明確でした(これが書かれた後に質問に編集されました)。 EFでの正しいアプローチについては、 Mandeeps answer を確認してください。


DateTime.Dateプロパティを使用して、日付のみの比較を実行できます。

DateTime a = GetFirstDate();
DateTime b = GetSecondDate();

if (a.Date.Equals(b.Date))
{
    // the dates are equal
}
120
Fredrik Mörk

時間部分をトリミングするには、クラス EntityFunctions を使用します。

using System.Data.Objects;    

var bla = (from log in context.Contacts
           where EntityFunctions.TruncateTime(log.ModifiedDate) ==  EntityFunctions.TruncateTime(today.Date)
           select log).FirstOrDefault();

ソース: http://social.msdn.Microsoft.com/Forums/en-US/csharpgeneral/thread/84d4e18b-7545-419b-9826-53ff1a0e2a62/

UPDATE

EF 6.0以降では、EntityFunctionsは DbFunctions に置き換えられています。

131
Mandeep Janjua

これはあなたの役に立つと思います。

EFデータで満たされたリポジトリ内の日付を比較する必要があるため、拡張子を作成しました。したがって、日付はLinqToEntities変換に実装されていないため、オプションではありませんでした。

コードは次のとおりです。

        /// <summary>
    /// Check if two dates are same
    /// </summary>
    /// <typeparam name="TElement">Type</typeparam>
    /// <param name="valueSelector">date field</param>
    /// <param name="value">date compared</param>
    /// <returns>bool</returns>
    public Expression<Func<TElement, bool>> IsSameDate<TElement>(Expression<Func<TElement, DateTime>> valueSelector, DateTime value)
    {
        ParameterExpression p = valueSelector.Parameters.Single();

        var antes = Expression.GreaterThanOrEqual(valueSelector.Body, Expression.Constant(value.Date, typeof(DateTime)));

        var despues = Expression.LessThan(valueSelector.Body, Expression.Constant(value.AddDays(1).Date, typeof(DateTime)));

        Expression body = Expression.And(antes, despues);

        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

この方法で使用できます。

 var today = DateTime.Now;
 var todayPosts = from t in turnos.Where(IsSameDate<Turno>(t => t.MyDate, today))
                                      select t);
24
jrojo

DBエンティティにDateプロパティを使用すると、例外が発生します。

"The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

次のようなものを使用できます。

  DateTime date = DateTime.Now.Date;

  var result = from client in context.clients
               where client.BirthDate >= date
                     && client.BirthDate < date.AddDays(1)
               select client;
10
algreat

別の方法がありますが、SecondDateが渡す変数の場合にのみ役立ちます。

DateTime startDate = SecondDate.Date;
DateTime endDate = startDate.AddDays(1).AddTicks(-1);
...
e => e.FirstDate.Value >= startDate && e.FirstDate.Value <= endDate

私はそれがうまくいくと思う

8
John Kaster

LINQ to Entitiesでこれを行うには、 サポートされているメソッド を使用する必要があります。

var year = someDate.Year;
var month = ...
var q = from r in Context.Records
        where Microsoft.VisualBasic.DateAndTime.Year(r.SomeDate) == year 
              && // month and day

Glyいですが、機能し、DBサーバーで実行されます。

8
Craig Stuntz

これも使用できます:

DbFunctions.DiffDays(date1, date2) == 0

6
user3829854

これにはDbFunctions.TruncateTime()メソッドを使用できます。

e => DbFunctions.TruncateTime(e.FirstDate.Value) == DbFunctions.TruncateTime(SecondDate);
4
Harsh Vyas

完全な日付時刻ではなく、DateTimeの Date プロパティを常に比較するだけです。

LINQクエリを作成するとき、クエリでdate.Dateを使用します。

var results = from c in collection
              where c.Date == myDateTime.Date
              select c;
3
Reed Copsey

これは私がこれを行う方法です。

DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
                EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));
3

// Linqユーザー/コーダー向けの注意

これにより、ユーザーからの入力を操作するときに日付が範囲内にあるかどうかを確認するための正確な比較が得られます-たとえば、日付ピッカー:

((DateTime)ri.RequestX.DateSatisfied).Date >= startdate.Date &&
        ((DateTime)ri.RequestX.DateSatisfied).Date <= enddate.Date

startdateとenddateは、日付ピッカーからの値です。

2
Leo Di Salty

誰かがここにグーグルやビンビンに到着した場合...コンパイルされた回避策:

http://blog.integratedsolution.eu/post/2011/02/06/-specific-type-member-Date-is-not-supported-in-LINQ-to-Entities.aspx

1
Braulio

次のように試すよりも時間がありません:

TimeSpan ts = new TimeSpan(23, 59, 59);
toDate = toDate.Add(ts);
List<AuditLog> resultLogs = 
    _dbContext.AuditLogs
    .Where(al => al.Log_Date >= fromDate && al.Log_Date <= toDate)
    .ToList();
return resultLogs;
1

以下のリンクを使用して、2つの日付を時間なしで比較できます。

private bool DateGreaterOrEqual(DateTime dt1, DateTime dt2)
        {
            return DateTime.Compare(dt1.Date, dt2.Date) >= 0;
        }

private bool DateLessOrEqual(DateTime dt1, DateTime dt2)
        {
            return DateTime.Compare(dt1.Date, dt2.Date) <= 0;
        }

compare関数は3つの異なる値を返します。-10 1は、dt1> dt2、dt1 = dt2、dt1を意味します

1
majid

これを試してください... 2つのDateTimesタイプのDateプロパティを比較するとうまくいきます:

PS。データベースが何千ものレコードをもたらす可能性があることを知っているときは、それは一時的な解決策であり、本当に悪い習慣です。

query = query.ToList()
             .Where(x => x.FirstDate.Date == SecondDate.Date)
             .AsQueryable();
0
Raskunho