EF- এ ডেটটাইম থেকে কেবলমাত্র তারিখের উপাদানগুলি কীভাবে তুলনা করবেন?


116

আমার দুটি তারিখের মান রয়েছে, একটি ইতিমধ্যে ডাটাবেসে সঞ্চিত এবং অন্যটি ব্যবহারকারী দ্বারা ডেটপিকার ব্যবহার করে নির্বাচিত। ব্যবহারের ক্ষেত্রে ডাটাবেস থেকে একটি নির্দিষ্ট তারিখ অনুসন্ধান করা।

পূর্বে ডাটাবেসে সন্নিবেশ করা মানটির সর্বদা সময় সময় থাকে 12:00:00, যেখানে চয়নকারী থেকে প্রবেশের তারিখের মতো আলাদা সময় উপাদান থাকে।

আমি কেবল তারিখের উপাদানগুলিতে আগ্রহী এবং সময় উপাদানটিকে উপেক্ষা করতে চাই।

সি # তে এই তুলনা করার উপায়গুলি কী কী?

এছাড়াও, লিনকিউতে এটি কীভাবে করবেন?

আপডেট: সত্তা থেকে লাইনকিতে, নিম্নলিখিতটি সূক্ষ্ম কাজ করে।

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

1
আপনি এই এসও প্রশ্নটিও একবার দেখে নিতে পারেন: stackoverflow.com/questions/683037/how-to-compare-dates-in-c/…
কুইন্টিন রবিনসন

উত্তর:


121

দ্রষ্টব্য: এই উত্তরটি লেখার সময়, EF- সম্পর্কটি অস্পষ্ট ছিল (এটি লেখার পরে প্রশ্নটিতে সম্পাদিত হয়েছিল)। EF- র সাথে সঠিক পদ্ধতির জন্য মান্ডিপস উত্তরটি দেখুন


আপনি DateTime.Dateকেবলমাত্র তারিখের তুলনা করতে সম্পত্তিটি ব্যবহার করতে পারেন ।

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

if (a.Date.Equals(b.Date))
{
    // the dates are equal
}

34
তারিখের তুলনা করা সহজ তবে প্রশ্নটি লিনকিউ সম্পর্কিত সংস্থাগুলির সাথে সম্পর্কিত যারা ডেট সম্পত্তিটিকে এসকিউএলে রূপান্তর করতে অক্ষম।
মিশাল কার্পেন্টিয়ার

1
@ মাইচালকার্পেন্টিয়ার: ভালো কথা। স্পষ্টতই এটি এখনও ওপি'র সমস্যা সমাধান করেছে।
ফ্রেডরিক মের্ক

6
এটি ডাটাবেসটিকে জিজ্ঞাসাবাদ করে না বরং সত্যের পরে সিএলআর / অ্যাপ্লিকেশন স্তরের ডেটা প্রক্রিয়া করে। আসল সমাধানটি হ'ল নীচের উত্তরে বর্ণিত সত্ত্বা ফাংশন.ট্রুনকেটটাইম (..) ফাংশনটি ব্যবহার করা, যেহেতু এটি কোয়েরিটি ডাটাবেসে প্রেরণ করে এবং স্টোরেজ স্তরটিতে প্রসেসিংয়ের অনুমতি দেয়। এটি ব্যতীত আপনি কোথায় / গণনা অনুচ্ছেদে তারিখের তুলনা যুক্তি এবং ফিল্টার করা ডেটা সম্পর্কে আরও কোয়েরি ব্যবহার করতে পারবেন না, যেহেতু আপনাকে প্রথমে অ্যাপ্লিকেশন স্তরের আংশিক ফলাফল টানতে হবে, যা পরিস্থিতিগুলিতে একটি ডিল-ব্রেকার হতে পারে তথ্য বৃহত বডি প্রক্রিয়া।
মার্চ

6
@ মার্চি হ্যাঁ, EntityFunctions.TruncateTimeঅবশ্যই এই দিনগুলি যাওয়ার উপায় বলে মনে হচ্ছে (এটি প্রশ্নটি জিজ্ঞাসা করার এক বছর পরেই প্রকাশ করা হয়েছিল। নেট 4 এ এটি উপলব্ধ হয়েছিল)।
ফ্রেডরিক মের্ক

1
System.Data.Entity.DbFunitions.TruncateTime () পদ্ধতিটি ব্যবহার করুন। আপনাকে এন্টি ফ্রেমওয়ার্কের একটি রেফারেন্স যুক্ত করতে হবে
অ্যাডেল 41

132

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.mic Microsoft.com/ Forums / en-US / csharpgeneral / thread / 84d4e18b-7545-419b-9826-53ff1a0e2a62/

হালনাগাদ

মতিন 6.0 এবং পরে EntityFunctions হিসাবে দ্বারা প্রতিস্থাপিত হয় DbFunctions


37
(কমপক্ষে) EF6 EntityFunctionsএর পক্ষে কেবল একটি নোট System.Data.Entity.DbFunctionsঅবচয় করা হয়েছে। এটি এর আগেও হতে পারে।
pquest

4
আমি এই সমাধান ঝাঁপ দ্রুত হবে না যেমন সত্যিই ধীর, আরো তথ্য: stackoverflow.com/questions/22776843/...
pajics

কোনও এসকিউএল ডাটাবেস নিয়ে কাজ করছে বলে মনে হচ্ছে না। আমি "এসকিউএল লজিক ত্রুটি বা অনুপস্থিত ডাটাবেস যেমন কোনও ফাংশন নেই: ট্রাঙ্কেটটাইম"।
শেডসোড়া

24

আমি মনে করি এটি আপনাকে সাহায্য করতে পারে।

আমি একটি এক্সটেনশান করেছি যেহেতু ইএফ ডেটা দ্বারা ভরাট সংগ্রহস্থলগুলিতে আমাকে তারিখগুলি তুলনা করতে হবে এবং তাই .ডিন্টি বিকল্প ছিল না যেহেতু এটি লিনকটোএন্টিটিজ অনুবাদে প্রয়োগ করা হয়নি।

কোডটি এখানে:

        /// <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);

10

আপনি যদি 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;

8

এটি লিনকিউ টু সত্তাগুলিতে করতে, আপনাকে সমর্থিত পদ্ধতিগুলি ব্যবহার করতে হবে :

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

কুরুচিপূর্ণ, তবে এটি কাজ করে, এবং এটি ডিবি সার্ভারে হয়ে গেছে।


8

এটি করার জন্য এখানে আলাদা উপায় রয়েছে তবে সেকেন্ডডেট যদি এমন পরিবর্তনশীল হয় যেটি আপনি প্রবেশ করছেন:

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

আমি মনে করি এটি কাজ করা উচিত


1
চমৎকার। আমার জন্য কাজ করেছেন। DateTime = x.Date;আমি স্পষ্টভাবে অনুপস্থিত ছিল। যদি আমি ব্যবহার করে থাকি var, বা তুলনাতে মান ইনলাইনটি থাকত তবে এটি রিপোর্ট করা ব্যতিক্রমের সাথে ব্যর্থ হয়েছিল। ধন্যবাদ।
টিম ক্রয়েডন

খুশী এটা কাজ করেছে, টিম। প্রতিক্রিয়া জানাতে দেরি হওয়ার জন্য দুঃখিত - আমি আসলে কিছুক্ষণের জন্য এসও তে লগ ইন করিনি।
জন কাস্টার

1
আপনি যদি পরিবর্তন e.FirstDate.Value <= endDateকরেন তবে e.FirstDate.Value < endDateএটিকে সরাতে পারেন .AddTicks(-1)
মার্কো ডি জিউউ

@ মারকোডজিউ আপনি ঠিক বলেছেন, এটি অবশ্যই কার্যকরভাবে কাজ করবে। প্রদর্শিত শর্তসাপেক্ষ প্রকাশটি সঠিক শুরু এবং শেষের তারিখের অন্তর্ভুক্তের তারিখের তুলনা করার উদ্দেশ্যে করা হয়েছে (ধরে নেওয়া হচ্ছে যে তারিখের সীমা মানগুলি একটি কোড খণ্ডে সেটআপ না করে শর্তে প্রেরণ করা হবে)) IOW, শর্তসাপেক্ষ তারিখের সময়কালের মান থেকে পৃথক হিসাবে বিবেচিত হয় ।
জন কাস্টার

6

আপনি এটি ব্যবহার করতে পারেন:

DbFunctions.DiffDays(date1, date2) == 0


4

আপনি এটির জন্য DbFunitions.TruncateTime () পদ্ধতি ব্যবহার করতে পারেন।

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

3

কেবল সর্বদা সম্পূর্ণ তারিখের পরিবর্তে ডেটটাইমের তারিখের সম্পত্তিটির তুলনা করুন ।

আপনি যখন আপনার লিনকিউ ক্যোয়ারী করবেন তখন তারিখটি ব্যবহার করুন query প্রশ্নটিতে তারিখ, অর্থাত:

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

10
আমি ত্রুটিটি পাচ্ছি "নির্দিষ্ট ধরণের সদস্য 'তারিখ' লিনকিউতে সত্তাগুলিতে সমর্থিত নয় Only কেবল আরম্ভকারী, সত্তা সদস্য এবং সত্তা নেভিগেশন বৈশিষ্ট্যগুলি সমর্থিত" কোন চিন্তা?
পেনসিলসেট

হ্যাঁ - আপনার সরবরাহকারী। তারিখের সম্পত্তিটি সরাসরি পরিচালনা করেন না। আপনাকে এটিকে বাইরে বের করতে হবে এবং তারিখগুলি পরে তুলনা করতে হবে।
রিড কোপসি

দুর্ভাগ্যক্রমে, তারিখ লিনক টু সত্তাগুলিতে ব্যবহার করা যাবে না। আশা করি এমএস শীঘ্রই সেই ওভারলোড সমর্থন যুক্ত করবে
জন কাস্টার

1
সর্বদা তারিখের সম্পত্তিটির তুলনা করবেন? আমি এই মন্তব্যে গুগল করেছি কারণ আমি ভাবছি যে এটি যদি সেরা অনুশীলন, তবে। থেকে সবসময় তারিখ সম্পত্তি, এমনকি যখন এটা ভালো কিছু ব্যবহার candidate.Date >= base.Date। তাত্ত্বিকভাবে, candidate.Dateসময়টি অবশ্যই> = 12:00:00 হতে হবে, সুতরাং তারিখের সম্পত্তিটি ব্যবহার করা নিরর্থক, তবে আমি রিডের পরামর্শের সাথে লেগে থাকব।
স্টিফেন হোসিং


2

// লিনক ব্যবহারকারী / কোডারদের জন্য নোট

কোনও ব্যবহারকারী থেকে ইনপুট নিয়ে কাজ করার সময় কোনও তারিখ সীমার মধ্যে পড়ে কিনা তা পরীক্ষা করার জন্য এটি আপনাকে সঠিক তুলনা দেয় - উদাহরণস্বরূপ:

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

যেখানে সূচনা এবং শেষের তারিখ একটি তারিখ চয়নকারীর মান।


1

সময় ছাড়া এই চেষ্টা করে দেখুন:

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;
        }

ফাংশনটির তুলনা করুন 3 টি আলাদা মান: -1 0 1 যার অর্থ ডিটি 1> ডিটি 2, ডিটি 1 = ডিটি 2, ডিটি 1


আপনি কেবল ডেটটাইম.কম্পিয়ার (ডিটি 1. তারিখ, ডিটি 2. তারিখ) কেন ফেরান না? এটি আপনার প্রয়োজনীয় সমস্ত করে তোলে।
জনি গ্রেবার

0

এটি ব্যবহার করে দেখুন ... দুটি তারিখ টাইম টাইপের মধ্যে তারিখের বৈশিষ্ট্যগুলির তুলনা করতে এটি দুর্দান্ত কাজ করে:

পুনশ্চ. এটি একটি স্টপগ্যাপ সমাধান এবং সত্যই খারাপ অভ্যাস, কখনই ব্যবহার করা উচিত নয় যখন আপনি জানেন যে ডাটাবেস হাজার হাজার রেকর্ড আনতে পারে ...

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

1
PS: ডেটটাইমগুলির সময় মূল্য থাকে এবং আমি কেবল তারিখের সাথে তুলনা করতে চাই usually
রাসকুনহো

2
এটি একটি খুব খারাপ সমাধান, ক্যোয়ারী সমস্ত রেকর্ড পাবে এবং কেবলমাত্র তারিখগুলি ফিল্টার করে ফেলবে। ডাটাবেসে যদি কয়েক মিলিয়ন রেকর্ড থাকে তবে এটি সমস্তটি গ্রাহ্য করবে এবং কেবলমাত্র তারিখগুলি ফিল্টার করবে। খুব খারাপ অভ্যাস।
ডেমেন্টিক

1
এটি একটি স্টপগ্যাপ সমাধান এবং সত্যই খারাপ অভ্যাস, কখনই ব্যবহার করা উচিত নয় যখন আপনি জানেন যে ডাটাবেস হাজার হাজার রেকর্ড আনতে পারে।
রাসকুনহো

যদি আপনি নিজের উত্তরে আপনার মন্তব্য যুক্ত করেন তবে আমি আমার ডাউন-ভোটটি সরিয়ে ফেলব। এই পৃষ্ঠাটি দেখার জন্য যে কেউ স্পষ্ট হওয়া উচিত যে আপনি প্রস্তাবিত সমাধানটি মন্তব্যগুলি না পড়েই খারাপ bad
ডেমেন্টিক

সাধারণভাবে একটি খারাপ ধারণা থাকা সত্ত্বেও, এই পদ্ধতির ফলে ছোট রেকর্ড সেট (<1000 রেকর্ড বা তাই) এর জন্য বিরাট উন্নত পারফরম্যান্সের ফলস্বরূপ, EF তারিখের তুলনাটি এসকিউএলে অনুবাদ করে। আমি দেখেছি কোয়েরিগুলি এক মিনিটেরও বেশি সময় থেকে সেকেন্ডের মধ্যে চলে এসকিউএল ইএফ যা কিছু উত্পন্ন করে তার পরিবর্তে মেমরিতে তারিখের তুলনা করে।
Extragorey
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.