2017-08-14 11 views
0

CRMエンティティをクエリするのにLINQを使用しています。以下は私のコードlinq to crmの日付範囲フィルタ

var data = svcContext.CreateQuery("myentity"); 
if (info.FromDate != null && info.ToDate != null) 
{ 
    data = data.Where(r => r.GetAttributeValue<DateTime>("rundate") >= info.FromDate.Value.Date && r.GetAttributeValue<DateTime>("rundate") <= info.ToDate.Value.Date); 
} 

これはfromDateからtoDateまでのすべてのレコードを返しますが、間違ったレコードを返した比較しながら、それはまた、時間の一部を考えるです。私は時間部分を切り捨て、比較のために日付部分のみを使用したい。私はすでにこの

1.

if (info.FromDate != null && info.ToDate != null) 
{ 
    data = data.Where(r => r.GetAttributeValue<DateTime>("rundate").Date >= info.FromDate.Value.Date && r.GetAttributeValue<DateTime>("rundate").Date <= info.ToDate.Value.Date); 
} 

2.

if (info.FromDate != null && info.ToDate != null) 
{ 
    data = data.Where(r => Convert.ToDateTime(r.Attributes["rundate"]).Date >= info.FromDate.Value.Date && Convert.ToDateTime(r.Attributes["rundate"]).Date <= info.ToDate.Value.Date); 
} 

3.

if (info.FromDate != null && info.ToDate != null) 
{ 
    data = data.Where(r => EntityFunctions.TruncateTime(r.GetAttributeValue<DateTime>("rundate")) >= info.FromDate.Value.Date && EntityFunctions.TruncateTime(r.GetAttributeValue<DateTime>("rundate")).Date <= info.ToDate.Value.Date); 
} 

これらすべてretuのようなコードを使用しましたrns "無効な 'where'の条件。 "エラー。日付部分と切り捨て部分だけで比較する方法ありがとうございました。

+0

であなたの記録を照会していないが単純に(レコードをフィルタ処理が、時間とみなさ返される)最初のクエリの後ToListメソッドを実行します。次に、結果に時間を費やさずにクエリを実行してください(それはオブジェクトへのLinqになりますので、すべてサポートされています) –

答えて

1

実際の時間が重要でない場合は、なぜあなたは

var data = svcContext.CreateQuery("myentity"); 
if (info.FromDate != null && info.ToDate != null) 
{ 
    var compareFromDate = info.FromDate.Value.Date; 
    var compareToDate = info.ToDate.Value.Date.AddDays(1); 
    data = data.Where(r => r.GetAttributeValue<DateTime>("rundate") >= compareFromDate && r.GetAttributeValue<DateTime>("rundate") < compareToDate); 
} 
0

CRM LINQプロバイダーにはLINQ to Objectsにはない制限がいくつかあります。

からCreateQuery結果にToListメソッド()を追加すると、あなたがやりたいことを可能にするはずである、オブジェクトにLINQを使用して変換します。あなたがする探している比較のために

、OLEオートメーションの小数日付フォーマットにcoverting (OADate)の場合、int型にキャストすると、日付のシリアル番号が渡されます。

そしてわかりやすくするために、私は述語を別の方法に移しました。

public override void Run() 
{ 
    using (var context = new Microsoft.Xrm.Sdk.Client.OrganizationServiceContext(svc)) 
    { 
     var result = (from e in context.CreateQuery("account").ToList() 
         .Where(ne => isBetween(ne.GetAttributeValue<DateTime>("createdon"), DateTime.MinValue, DateTime.Now)) 
         select e).ToList();  
    } 
} 

private bool isBetween(DateTime value, DateTime min, DateTime max) 
{ 
    var val = (int)value.ToOADate(); 
    return val >= (int)min.ToOADate() || val <= (int)max.ToOADate(); 
} 
+0

返信ありがとう@Aronしかし、私はcontext.CreateQuery( "account")を使用できません。およそ5000のレコードを持ち、増加し続けています。私が.ToList()を呼び出すと、メモリ内のすべてのレコードがロードされ、パフォーマンスの観点からは不要なフィルタがロードされます。私はあなたのソリューションを使用しようとしました.ToList()と同じエラーが返されます "無効な 'ここで'条件..." – LoneWolf