2つの日付値があります。1つは既にデータベースに格納されており、もう1つはDatePickerを使用してユーザーが選択します。ユースケースは、データベースから特定の日付を検索することです。
以前にデータベースに入力された値は、常に12:00:00の時間コンポーネントを持ちます。ピッカーから入力された日付は異なる時間コンポーネントを持っています。
日付コンポーネントのみに興味があり、時間コンポーネントは無視したいです。
C#でこの比較を行う方法は何ですか?
また、LINQでこれを行う方法は?
更新:LINQ to Entitiesでは、以下が正常に機能します。
e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0
注:この回答を書いた時点では、EF関係は不明確でした(これが書かれた後に質問に編集されました)。 EFでの正しいアプローチについては、 Mandeeps answer を確認してください。
DateTime.Date
プロパティを使用して、日付のみの比較を実行できます。
DateTime a = GetFirstDate();
DateTime b = GetSecondDate();
if (a.Date.Equals(b.Date))
{
// the dates are equal
}
時間部分をトリミングするには、クラス EntityFunctions
を使用します。
using System.Data.Objects;
var bla = (from log in context.Contacts
where EntityFunctions.TruncateTime(log.ModifiedDate) == EntityFunctions.TruncateTime(today.Date)
select log).FirstOrDefault();
UPDATE
EF 6.0以降では、EntityFunctionsは DbFunctions に置き換えられています。
これはあなたの役に立つと思います。
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);
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;
別の方法がありますが、SecondDateが渡す変数の場合にのみ役立ちます。
DateTime startDate = SecondDate.Date;
DateTime endDate = startDate.AddDays(1).AddTicks(-1);
...
e => e.FirstDate.Value >= startDate && e.FirstDate.Value <= endDate
私はそれがうまくいくと思う
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サーバーで実行されます。
これも使用できます:
DbFunctions.DiffDays(date1, date2) == 0
これにはDbFunctions.TruncateTime()メソッドを使用できます。
e => DbFunctions.TruncateTime(e.FirstDate.Value) == DbFunctions.TruncateTime(SecondDate);
完全な日付時刻ではなく、DateTimeの Date プロパティを常に比較するだけです。
LINQクエリを作成するとき、クエリでdate.Dateを使用します。
var results = from c in collection
where c.Date == myDateTime.Date
select c;
これは私がこれを行う方法です。
DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));
// Linqユーザー/コーダー向けの注意
これにより、ユーザーからの入力を操作するときに日付が範囲内にあるかどうかを確認するための正確な比較が得られます-たとえば、日付ピッカー:
((DateTime)ri.RequestX.DateSatisfied).Date >= startdate.Date &&
((DateTime)ri.RequestX.DateSatisfied).Date <= enddate.Date
startdateとenddateは、日付ピッカーからの値です。
誰かがここにグーグルやビンビンに到着した場合...コンパイルされた回避策:
次のように試すよりも時間がありません:
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;
以下のリンクを使用して、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を意味します
これを試してください... 2つのDateTimesタイプのDateプロパティを比較するとうまくいきます:
PS。データベースが何千ものレコードをもたらす可能性があることを知っているときは、それは一時的な解決策であり、本当に悪い習慣です。
query = query.ToList()
.Where(x => x.FirstDate.Date == SecondDate.Date)
.AsQueryable();