EF6 क्वेरी अनुवादक DateTime.TimeOfDay
का समर्थन नहीं करता, और Oracle प्रदाता DbFunctions.CreateTime
और TimeSpan
मापदंडों स्थिरांक का समर्थन नहीं करता /।
फिर भी वहाँ के रूप में एक और उत्तर ने सुझाव दिया string
करने के लिए DateTime
से भंडारण स्विच करने से पहले कुछ विकल्प हैं।
सबसे पहले, आप (क्वेरी पैरामीटर) अलग-अलग वैरिएबल में उन्हें निकालने या तो द्वारा समय घटकों की तुलना कर सकते समानता जांच के लिए:
var hour = viewmodel.ExecutionTime.Hours;
var minute = viewmodel.ExecutionTime.Minutes;
var second = viewmodel.ExecutionTime.Seconds;
var db0010016 = _idb0010016Rep.FindBy(e =>
e.ExecutionTime.Hour == hour && e.ExecutionTime.Minute == minute && e.ExecutionTime.Second == second)
.FirstOrDefault();
या नकली DateTime
चर (queryParameter) में:
var executionTime = DateTime.Today + viewmodel.ExecutionTime;
var db0010016 = _idb0010016Rep.FindBy(e =>
e.ExecutionTime.Hour == executionTime.Hour && e.ExecutionTime.Minute == executionTime.Minute && e.ExecutionTime.Second == executionTime.Second)
.FirstOrDefault();
दूसरा, आप सेकेंड में परिवर्तित समय के साथ काम कर सकते हैं।
var executionTime = (int)viewmodel.ExecutionTime.TotalSeconds;
var db0010016 = _idb0010016Rep.FindBy(e =>
60 * 60 * e.ExecutionTime.Hour + 60 * e.ExecutionTime.Minute + e.ExecutionTime.Second == executionTime)
.FirstOrDefault();
लेकिन सभी कि मैन्युअल काफी कष्टप्रद और त्रुटि प्रवण है कर: यह आप भी किसी भी तुलना करने देता है।
public static partial class QueryableExtensions
{
public static IQueryable<T> ConvertTimeSpans<T>(this IQueryable<T> source)
{
var expr = new TimeSpanConverter().Visit(source.Expression);
return source == expr ? source : source.Provider.CreateQuery<T>(expr);
}
class TimeSpanConverter : ExpressionVisitor
{
static readonly Expression<Func<DateTime, int>> ConvertTimeOfDay = dt =>
60 * (60 * dt.Hour + dt.Minute) + dt.Second;
static int ConvertTimespan(TimeSpan ts) =>
60 * (60 * ts.Hours + ts.Minutes) + ts.Seconds;
protected override Expression VisitMember(MemberExpression node)
{
if (node.Type == typeof(TimeSpan))
{
if (node.Member.DeclaringType == typeof(DateTime) && node.Member.Name == nameof(DateTime.TimeOfDay))
return ConvertTimeOfDay.ReplaceParameter(0, base.Visit(node.Expression));
// Evaluate the TimeSpan value, convert and wrap it into closure (to keep non const semantics)
return ConvertTimespan(base.VisitMember(node).Evaluate<TimeSpan>()).ToClosure().Body;
}
return base.VisitMember(node);
}
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.Left.Type == typeof(TimeSpan))
return Expression.MakeBinary(node.NodeType, Visit(node.Left), Visit(node.Right));
return base.VisitBinary(node);
}
}
static T Evaluate<T>(this Expression source) => Expression.Lambda<Func<T>>(source).Compile().Invoke();
static Expression<Func<T>> ToClosure<T>(this T value) =>() => value;
static Expression ReplaceParameter(this LambdaExpression source, int index, Expression target) =>
new ParameterReplacer { Source = source.Parameters[index], Target = target }.Visit(source.Body);
class ParameterReplacer : ExpressionVisitor
{
public ParameterExpression Source;
public Expression Target;
protected override Expression VisitParameter(ParameterExpression node) => node == Source ? Target : node;
}
}
यह दो छोटे कस्टम ExpressionVisitor
कक्षाओं का उपयोग करता है अपने viewModel.ExecutionTime
के समान DateTime.TimeOfDay
संपत्ति और TimeSpan
वर्ग गुण परिवर्तित करने के लिए: क्या मैं की पेशकश कर सकते है छोटे उपयोगिता वर्ग उपलब्ध कराने के कस्टम विस्तार विधि है।
अब आप इस तरह आपकी मूल क्वेरी का उपयोग किया जाना चाहिए:
var db0010016 = _idb0010016Rep.GetAll()
.Where(e => e.ExecutionTime.TimeOfDay == viewmodel.ExecutionTime)
.ConvertTimeStamps() // the magic happens here
.FirstOrDefault();
आप के बजाय सेकंड के मिलीसेकेंड का उपयोग करना चाहते मामले में, आप सभी की जरूरत के रूप में इस TimeSpanConverter
कक्षा में प्रथम दो बयान बदलने के लिए है:
static readonly Expression<Func<DateTime, int>> ConvertTimeOfDay = dt =>
1000 * (60 * (60 * dt.Hour + dt.Minute) + dt.Second) + dt.Millisecond;
static int ConvertTimespan(TimeSpan ts) =>
1000 * (60 * (60 * ts.Hours + ts.Minutes) + ts.Seconds) + ts.Milliseconds;
जब आप पहला कोड चलाते हैं तो आपको क्या त्रुटि मिलती है? –
https://stackoverflow.com/questions/39822588/how-to-convert-datetime-to-timespan-in-entity-framework-query?rq=1 का डुप्लिकेट जैसा लगता है। उस उत्तर को जांचें क्योंकि यह चीजों को तारों में परिवर्तित करने से बेहतर है! – user2612030