public class Category : IAuditableEntity { public int Id { get; set; } public Category() { Products = new HashSet<Product>(); } public DateTime? CreatedDateTime { get; set; } //Here public string Name { get; set; } public string Title { get; set; } public virtual ICollection<Product> Products { get; set; } }
Bootstrap 4.4.0 منتشر شد
- New responsive containers! Over a year in the making, fluid up to a particular breakpoint, available for all responsive tiers.
- New responsive
.row-cols
classes for quickly specifying the number of columns across breakpoints. This one is huge for those of you who have asked for responsive card decks.
این زیرنویسها فرمت ویژهای دارند:
<li class="transcript-module"> Introduction to ASP.NET MVC 4 <ul> <li class="transcript-clip" data-p="author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=0&course=mvc4-building"><a href="javascript:void(0)" onclick="LaunchPlayerWindow('http://pluralsight.com/training', 'author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=0&course=mvc4-building');">Introduction</a><br /> <div> <a href="javascript:void(0)" onclick="p(this);" data-s="1.636">Hi, this is Scott Allen and this is the first module in the course design</a> </div> </li> <li class="transcript-clip" data-p="author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=1&course=mvc4-building"><a href="javascript:void(0)" onclick="LaunchPlayerWindow('http://pluralsight.com/training', 'author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=1&course=mvc4-building');">Web Platform Installer</a><br /> <div> ...
public class TranscriptClip { public string Title { set; get; } public IList<TranscriptItem> TranscriptItems { set; get; } } public class TranscriptItem { public double StartTime { set; get; } public string Text { set; get; } }
برای استخراج این اطلاعات، یکی از بهترین ابزارها، کتابخانه HTML Agility pack است که توسط آن میتوان به liهای یاد شده دسترسی یافت:
var nodes = doc.DocumentNode.SelectNodes("//li[@class='transcript-clip']/div");
using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web; using HtmlAgilityPack; namespace PluralsightTranscripts { public class TranscriptClip { public string Title { set; get; } public IList<TranscriptItem> TranscriptItems { set; get; } } public class TranscriptItem { public double StartTime { set; get; } public string Text { set; get; } } public class ExtractSubtitle { public static void ConvertToSrt(string fileName) { var transcriptClips = extractItems(fileName); var itemNumber = 1; foreach (var item in transcriptClips) { transcriptClipToSrt(item, itemNumber); itemNumber++; } } private static void transcriptClipToSrt(TranscriptClip item, int itemNumber) { var count = item.TranscriptItems.Count; var srtFileContent = transcriptItemsToSrt(item.TranscriptItems, count); var fileName = removeIllegalCharacters(string.Format("{0}-{1}.srt", itemNumber.ToString("00"), item.Title)); File.WriteAllText(fileName, srtFileContent); } private static string transcriptItemsToSrt(IList<TranscriptItem> items, int count) { var lineNumber = 1; var sb = new StringBuilder(); for (int row = 0; row < count; row++) { sb.AppendLine(lineNumber.ToString(CultureInfo.InvariantCulture)); sb.AppendLine(getTimeLine(items, count, row)); sb.AppendLine(items[row].Text); sb.AppendLine(string.Empty); lineNumber++; } return sb.ToString(); } private static string getTimeLine(IList<TranscriptItem> items, int count, int row) { var startTs = TimeSpan.FromSeconds(items[row].StartTime); var endTs = row + 1 < count ? TimeSpan.FromSeconds(items[row + 1].StartTime) : TimeSpan.FromSeconds(items[row].StartTime + 5); return string.Format("{0} --> {1}", timeSpanToString(startTs), timeSpanToString(endTs)); } private static string timeSpanToString(TimeSpan lineTs) { return string.Format("{0}:{1}:{2},{3}", lineTs.Hours.ToString("D2"), lineTs.Minutes.ToString("D2"), lineTs.Seconds.ToString("D2"), lineTs.Milliseconds.ToString("D3")); } private static string removeIllegalCharacters(string fileName) { string regexSearch = string.Format("{0}{1}", new string(Path.GetInvalidFileNameChars()), new string(Path.GetInvalidPathChars())); var r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch))); return r.Replace(fileName, "."); } private static IList<TranscriptClip> extractItems(string fileName) { var htmlContent = File.ReadAllText(fileName); var results = new List<TranscriptClip>(); var doc = new HtmlDocument { OptionCheckSyntax = true, OptionFixNestedTags = true, OptionAutoCloseOnEnd = true, OptionDefaultStreamEncoding = Encoding.UTF8 }; doc.LoadHtml(htmlContent); var nodes = doc.DocumentNode.SelectNodes("//li[@class='transcript-clip']/div"); foreach (var node in nodes) { var itemsList = new List<TranscriptItem>(); var title = node.ParentNode.ChildNodes.First(x => x.Name == "a").InnerText; foreach (var childNode in node.ChildNodes) { if (childNode.Name != "a") continue; var dataS = childNode.Attributes.First(x => x.Name == "data-s"); itemsList.Add(new TranscriptItem { StartTime = double.Parse(dataS.Value), Text = HttpUtility.HtmlDecode(childNode.InnerText.Trim()) }); } results.Add(new TranscriptClip { TranscriptItems = itemsList, Title = title }); } return results; } } }
فرمت SRT ساختار سادهای دارد. هر گفتگوی آن حداقل از سه سطر تشکیل میشود. سطر اول یک شماره خود افزاینده است. سطر دوم زمان شروع و پایان گفتگو را مشخص میکند و سطر سوم بیانگر متن گفتگو است. برای مثال:
1 00:00:01,636 --> 00:00:05,616 Hi, this is Scott Allen and this is the first module in the course design
دریافت پروژه کامل این مطلب
PluralsightTranscripts.zip
یک لامپ و سوئیچ برق را درنظر بگیرید. زمانیکه لامپ مشاهده میکند سوئیچ برق در حالت روشن قرار گرفتهاست، روشن خواهد شد و برعکس. در اینجا به سوئیچ، subject و به لامپ، observer گفته میشود. هر زمان که حالت سوئیچ تغییر میکند، از طریق یک callback، وضعیت خود را به observer اعلام خواهد کرد. علت استفاده از callbackها، ارائه راهحلهای عمومی است تا بتواند با انواع و اقسام اشیاء کار کند. به این ترتیب هر بار که شیء observer از نوع متفاوتی تعریف میشود (مثلا بجای لامپ یک خودرو قرار گیرد)، نیازی نخواهد بود تا subject را تغییر داد.
عموما به شیءایی که قرار است وضعیت را مشاهده یا رصد کند، Observer گفته میشود و به شیءایی که قرار است وضعیت آن رصد شود Observable یا Subject گفته میشود.
بد نیست بدانید این الگو یکی از کلیدیترین بخشهای معماری لایه بندی MVC نیز میباشد.
همچنین این نکته حائز اهمیت است که این الگو ممکن است باعث نشتی حافظه هم شود و به این مشکل Lapsed Listener Problem میگویند. یعنی یک listener وجود دارد که تاریخ آن منقضی شده، ولی هنوز در حافظه جا خوش کردهاست. این مشکل برای زبانهای شیءگرایی که با سیستمی مشابه GC پیاده سازی میشوند، رخ میدهد. برای جلوگیری از این حالت، برنامه نویس باید این مشکل را با رجیستر کردنها و عدم رجیستر یک شنوده، در مواقع لزوم حل کند. در غیر این صورت این شنونده بی جهت، یک ارتباط را زنده نگه داشته و حافظهی منبع را به هدر میدهد.
مثال: ما یک کلید داریم که سه کلاس RedLED،GreenLED و BlueLED قرار است آن را مشاهده و وضعیت کلید را رصد کنند.
برای پیاده سازی این الگو، ابتدا یک کلاس انتزاعی را با نام Observer که دارای متدی به نام Update است، ایجاد میکنیم. متغیر از نوع کلاس Observable را بعدا ایجاد میکنیم:
public abstract class Observer { protected Observable Observable; public abstract void Update(); }
public class Observable { private readonly List<Observer> _observers = new List<Observer>(); public void Attach(Observer observer) { _observers.Add(observer); } public void Dettach(Observer observer) { _observers.Remove(observer); } public void NotifyAllObservers() { foreach (var observer in _observers) { observer.Update(); } } }
حال کلاس Switch را با ارث بری از کلاس Observable مینویسیم:
public class Switch:Observable { private bool _state; public bool ChangeState { set { _state = value; NotifyAllObservers(); } get { return _state; } } }
برای هر سه چراغ، رنگی هم داریم:
public class RedLED:Observer { private bool _on = false; public override void Update() { _on = !_on; Console.WriteLine($"Red LED is {((_on) ? "On" : "Off")}"); } }
public class GreenLED:Observer { private bool _on = false; public override void Update() { _on = !_on; Console.WriteLine($"Green LED is {((_on) ? "On" : "Off")}"); } }
public class BlueLED:Observer { private bool _on = false; public override void Update() { _on = !_on; Console.WriteLine($"Blue LED is {((_on) ? "On" : "Off")}"); } }
var greenLed=new GreenLED(); var redLed=new RedLED(); var blueLed=new BlueLED(); var switchKey=new Switch(); switchKey.Attach(greenLed); switchKey.Attach(redLed); switchKey.Attach(blueLed); switchKey.ChangeState = true; switchKey.ChangeState = false;
Green LED is On Red LED is On Blue LED is On Green LED is Off Red LED is Off Blue LED is Off
معرفی استاندارد سورس باز #C
Moving the standards work into the open, under the .NET Foundation, makes it easier for standardization work. Everything from language innovation and feature design through implementation and on to standardization now takes place in the open. It will be easier to ask questions among the language design team, the compiler implementers, and the standards committee. Even better, those conversations will be public.
{ "userIsAuthorizedForCourseTranscripts": false, "modules": [ { "title": "Course Overview", "clips": [ { "title": "Course Overview", "playerParameters": "author=scott-allen&name=aspdotnet-core-1-0-fundamentals-m0&mode=live&clip=0&course=aspdotnet-core-1-0-fundamentals", "transcripts": [ ] } ] }, { "title": "Building Your First ASP.NET Core Application", "clips": [ { "title": "Introduction", "playerParameters": "author=scott-allen&name=aspdotnet-core-1-0-fundamentals-m1&mode=live&clip=0&course=aspdotnet-core-1-0-fundamentals", "transcripts": [ { "displayTime": 0.0, "text": "Hi! This is Scott, and this course will help you build your first application with ASP.NET Core." }, { "displayTime": 7.0, "text": "In this course, we'll be using Visual Studio and the new ASP.NET Framework to build a web application that" } ] } ] } ] }
public class PluralsightCourse { public bool UserIsAuthorizedForCourseTranscripts { get; set; } public PluralsightCourseItems[] Modules { get; set; } } public class PluralsightCourseItems { public string Title { get; set; } public PluralsightCourseClip[] Clips { get; set; } } public class PluralsightCourseClip { public string Title { get; set; } public string PlayerParameters { get; set; } public PluralsightCourseClipTranscript[] Transcripts { get; set; } } public class PluralsightCourseClipTranscript { public float DisplayTime { get; set; } public string Text { get; set; } }
بارگذاری آن توسط کتابخانهی JSON.NET به صورت ذیل خواهد بود:
public static PluralsightCourse ProcessJsonFile(string jsonData) { return JsonConvert.DeserializeObject<PluralsightCourse>(jsonData); }
کدهای کامل این برنامه را از اینجا میتوانید دریافت کنید:
PluralsightJsonTranscripts.V1.0.7z
هنگامی که حجم دادهها کم باشد شاید روش دسترسی و الگوریتم مورد استفاده اهمیتی نداشته باشد اما با افزایش حجم دادهها روشهای بهینهتر تاثیر مستقیم در کارایی برنامه دارند.
در این مثال سعی بر این است که در یک سناریوی خاص تفاوت بین Dictionary و List را بررسی کنیم :
فرض کنید 2 کلاس Student و Grade موجود است که وظیفهی نگهداری اطلاعات دانش آموز و نمره را بر عهده دارند.
public class Grade { public Guid StudentId { get; set; } public string Value { get; set; } public static IEnumerable<Grade> GetData() { for (int i = 0; i < 10000; i++) { yield return new Grade { StudentId = GuidHelper.ListOfIds[i], Value = "Value " + i }; } } } public class Student { public Guid Id { get; set; } public string Name { get; set; } public string Grade { get; set; } public static IEnumerable<Student> GetStudents() { for (int i = 0; i < 10000; i++) { yield return new Student { Id = GuidHelper.ListOfIds[i], Name = "Name " + i }; } } }
public class GuidHelper { public static List<Guid> ListOfIds=new List<Guid>(); static GuidHelper() { for (int i = 0; i < 10000; i++) { ListOfIds.Add(Guid.NewGuid()); } } }
ابتدا از LINQ روی لیست برای پیدا کردن نمرهی مورد نظر استفاده کرده و در روش دوم برای پیدا کردن نمرهی هر دانش آموز از Dictionary استفاده شده :
internal class Program { private static void Main(string[] args) { var stopwatch = new Stopwatch(); List<Grade> grades = Grade.GetData().ToList(); List<Student> students = Student.GetStudents().ToList(); stopwatch.Start(); foreach (Student student in students) { student.Grade = grades.Single(x => x.StudentId == student.Id).Value; } stopwatch.Stop(); Console.WriteLine("Using list {0}", stopwatch.Elapsed); stopwatch.Reset(); students = Student.GetStudents().ToList(); stopwatch.Start(); Dictionary<Guid, string> dictionary = Grade.GetData().ToDictionary(x => x.StudentId, x => x.Value); foreach (Student student in students) { student.Grade = dictionary[student.Id]; } stopwatch.Stop(); Console.WriteLine("Using dictionary {0}", stopwatch.Elapsed); Console.ReadKey(); } }
همانگونه که مشاهده میشود در این سناریو خواندن نمره از روی Dictionary بر اساس 'کلید' بسیار سریعتر از انجام یک پرس و جوی LINQ روی لیست است.
زمانی که از LINQ on list
student.Grade = grades.Single(x => x.StudentId == student.Id).Value;
زمانی که از Dictonary
student.Grade = dictionary[student.Id];
در نتیجه اگر نیاز به پیدا کردن اطلاعات بر اساس یک مقدار یکتا یا کلید باشد تبدیل اطلاعات به Dictionary و خواندن از آن بسیار به صرفهتر است.
تفاوت این 2 روش وقتی مشخص میشود که میزان دادهها زیاد باشد.
در همین رابطه (1 ، 2)
DictionaryVsList.zip
نکته بعدی جهت فعال سازی EnableCors چه کار خاصی باید انجام شود؟
من فعال سازی انجام دادم و در WebApiConfig برای همه کنترلرها فعال سازی انجام دادم اما آدرس login ظاهرا جز کنترلرها نیست این تنظیمات اعمال نمیشود و عملا برنامه بلا استفاده خواهد شد. قصد من استفاده از توکن بین چند دامنه خاص است. اما فعلا ازمایشی جهت استفاده همه دامنهها فعال سازی انجام شده ولی در عمل کار نمیکند. و خطای CORS در مرورگر دریافت میشود.
جهت اعمال به آدرس لاگین چه باید کرد نمونه کد اعمال CORS
public static class WebApiConfig { public static void Register(HttpConfiguration config) { var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); // ... } }
- اضافه کردن اسمبلیها به صورت دستی به پروژه و تنظیم Build Action آنها به Embedded Resource
- تنظیم فایل csproj پروژه برای Embed کردن خودکار رفرنسهای پروژه در زمان Build
روش اول
روش دوم
<Target Name="EmbedReferencedAssemblies" AfterTargets="ResolveAssemblyReferences"> <ItemGroup> <AssembliesToEmbed Include="@(ReferenceCopyLocalPaths)" /> <EmbeddedResource Include="@(AssembliesToEmbed)" Condition="'%(AssembliesToEmbed.Extension)' == '.dll'"> <LogicalName>%(AssembliesToEmbed.DestinationSubDirectory)%(AssembliesToEmbed.Filename)%(AssembliesToEmbed.Extension)</LogicalName> </EmbeddedResource> </ItemGroup> <Message Importance="high" Text="Embedding: @(AssembliesToEmbed->'%(DestinationSubDirectory)%(Filename)%(Extension)', ', ')" /> </Target> <Target Name="DeleteAllReferenceCopyLocalPaths" AfterTargets="Build"> <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" /> </Target>
همانطور که در تصویر بالا نیز مشاهده میکنید، اسمبلیهای ارجاعی برنامه TestApp به صورت Resource به آن اضافه شدهاند.
نحوه بارگذاری اسمبلیهای Embed شده
در پروژههای WPF، در OnStartup event کلاس App و در پروژههای WinForm در متد Main کلاس Program، قطعه کد زیر را وارد میکنیم:
private void App_OnStartup( object sender, StartupEventArgs e ) { AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly; var assembly = Assembly.GetExecutingAssembly(); foreach (var name in assembly.GetManifestResourceNames()) { if ( name.ToLower() .EndsWith( ".resources" ) || !name.ToLower() .EndsWith( ".dll" ) ) continue; EmbeddedAssembly.Load( name, name ); } } static Assembly OnResolveAssembly( object sender, ResolveEventArgs args ) { var fields = args.Name.Split( ',' ); var name = fields[0]; var culture = fields[2]; if ( name.EndsWith( ".resources" ) && !culture.EndsWith( "neutral" ) ) return null; return EmbeddedAssembly.Get( args.Name ); }
با استفاده از رویداد AssemblyResolve می توان اسمبلی Embed شده را در زمانیکه نیاز به آن است، بارگذاری کرد. کد مربوط به کلاس EmbeddedAssembly نیز به این صورت میباشد:
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Security.Cryptography; public static class EmbeddedAssembly { static Dictionary< string, Assembly > _dic; public static void Load( string embeddedResource, string fileName ) { if ( _dic == null ) _dic = new Dictionary< string, Assembly >(); byte[] ba; Assembly asm; var curAsm = Assembly.GetExecutingAssembly(); using ( var stm = curAsm.GetManifestResourceStream( embeddedResource ) ) { if ( stm == null ) return; ba = new byte[(int)stm.Length]; stm.Read( ba, 0, (int)stm.Length ); try { asm = Assembly.Load( ba ); _dic.Add( asm.GetName().Name, asm ); return; } catch { } } bool fileOk; string tempFile; using ( var sha1 = new SHA1CryptoServiceProvider() ) { var fileHash = BitConverter.ToString( sha1.ComputeHash( ba ) ) .Replace( "-", string.Empty ); tempFile = Path.GetTempPath() + fileName; if ( File.Exists( tempFile ) ) { var bb = File.ReadAllBytes( tempFile ); var fileHash2 = BitConverter.ToString( sha1.ComputeHash( bb ) ) .Replace( "-", string.Empty ); fileOk = fileHash == fileHash2; } else { fileOk = false; } } if ( !fileOk ) { File.WriteAllBytes( tempFile, ba ); } asm = Assembly.LoadFile( tempFile ); _dic.Add( asm.GetName().Name, asm ); } public static Assembly Get( string assemblyFullName ) { if ( _dic == null || _dic.Count == 0 ) return null; var name = new AssemblyName( assemblyFullName ).Name; return _dic.ContainsKey( name ) ? _dic[name] : null; } }
با استفاده از متد Load کلاس بالا، کل اسمبلیهایی که بارگذاری شدهاند در یک دیکشنری استاتیک نگهداری میشوند. ابتدا اسمبلیها را با استفاده از []byte بارگذاری میکنیم و در صورتیکه بارگذاری اسمبلی با خطایی مواجه شود، بارگذاری را با استفاده از فایل temp انجام میدهیم (که معمولا برای فایلهای unmanaged این مورد اتفاق میافتد).
با استفاده از متد Get که در زمان نیاز به یک اسمبلی توسط AssemblyResolve فراخوانی میشود، اسمبلی مربوطه از دیکشنری پیدا شده و برگشت داده میشود.
نکته ها
- در صورتیکه بخواهید فایلی را از Embed کردن خودکار (روش دوم) استثناء کنید، باید از Condition استفاده کنید:
<Target Name="EmbedReferencedAssemblies" AfterTargets="ResolveAssemblyReferences"> <ItemGroup> <AssembliesToEmbed Include="@(ReferenceCopyLocalPaths)" /> <EmbeddedResource Include="@(AssembliesToEmbed)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(AssembliesToEmbed.Filename)', '^((?!Microsoft).)*$')) And '%(AssembliesToEmbed.Extension)' == '.dll'"> <LogicalName>%(AssembliesToEmbed.DestinationSubDirectory)%(AssembliesToEmbed.Filename)%(AssembliesToEmbed.Extension)</LogicalName> </EmbeddedResource> </ItemGroup> <Message Importance="high" Text="Embedding: @(AssembliesToEmbed->'%(DestinationSubDirectory)%(Filename)%(Extension)', ', ')" /> </Target> <Target Name="DeleteAllReferenceCopyLocalPaths" AfterTargets="Build"> <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)', '^((?!Microsoft).)*$')) Or '%(Extension)' == '.xml'" /> </Target>
- در صورتیکه بعد از اجرای برنامه و یا اجرای به صورت دیباگ با خطای Stackoverflow مواجه شدید که به خاطر ارجاعات زیاد Resourceهای برنامه پیش میآید، کد زیر را به فایل AssemblyInfo، در پوشه Properties اضافه کنید:
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
- در صورتیکه پروژه شما از نوع Office Add-Ins باشد، باید در کد مربوط به AssemblyResolve را در فایل ThisAddIn.Designer.cs (در صورت عدم تغییر نام) به متد Initialize اضافه کنید و دستور بارگذاری را در متد ThisAddIn_Startup اضافه کنید. نکته خیلی مهم: در فایل csproj حتما در قسمت Condition باید اسمبلیهایی را که با نام Microsoft شروع میشوند، از Embed شدن استثناء کنید و در قسمت DeleteAllReferenceCopyLocalPaths مقدار "AfterTargets="VisualStudioForApplicationsBuild را قرار دهید (تا امکان Build پروژه برای شما باشد) و همچنین پسوند vsto را نیز نباید حذف کنید.
EF Code First #1
کدش از کتاب Code First که معرفی کردین استفاده کردم اما کد خودتون خطا نداره
using System; using System.Collections.Generic; namespace ChapterOneProject { public class Patient { public Patient() { Visits = new List<Visit>(); } public int Id { get; set; } public string Name { get; set; } public DateTime BirthDate { get; set; } //[ForeignKey("AnimalTypeId")] public AnimalType AnimalType { get; set; } //public int AnimalTypeId { get; set; } public DateTime FirstVisit { get; set; } public List<Visit> Visits { get; set; } } public class Visit { [Key] public int Id { get; set; } public DateTime Date { get; set; } public String ReasonForVisit { get; set; } public String Outcome { get; set; } public Decimal Weight { get; set; } //[ForeignKey("PatientId")] //public virtual Patient Patient { get; set; } public int PatientId { get; set; } } public class AnimalType { public int Id { get; set; } public string TypeName { get; set; } } }
کد کانتکست
public class VetContext : DbContext { public DbSet<Patient> Patients { get; set; } public DbSet<Visit> Visits { get; set; } //public DbSet<AnimalType> AnimalTypes { get; set; } }
var dog = new AnimalType { TypeName = "Dog" }; var visit = new List<Visit> { new Visit { Date = new DateTime(2011, 9, 1), Outcome = "Test", ReasonForVisit = "Test", Weight = 32, } }; var patient = new Patient { Name = "Sampson", BirthDate = new DateTime(2008, 1, 28), AnimalType = dog, Visits = visit, }; using (var context = new VetContext()) { context.Patients.Add(patient); context.SaveChanges(); }
کدهای دیگه تست کردم مشکلی نداشت اما این مورد ؟
با profiler چک کردم خطای عدم توانایی در تبدیل نوع datetime2 به datetime میده