مطالب
نحوه‌ی صحیح فراخوانی SQL Aggregate Functions حین استفاده از LINQ

SQL Aggregate Functions که مد نظر شما هستند مانند Min ، Max ، Sum و امثال آن. بحث LINQ هم زمانیکه از الگوی Repository استفاده شود مستقل از نوع ORM مورد نظر خواهد شد؛ بنابراین در اینجا مقصود از LINQ می‌تواند LINQ to SQL ، LINQ to Entities ، LINQ to NHibernate و کلا هر نوع ORM دیگری با پشتیبانی از LINQ باشد.
صورت مساله هم این است: آیا نوشتن عبارت LINQ ایی به شکل زیر صحیح است؟
decimal amount = respository.Transactions
.Where(t=>t.TransactionDate>new DateTime(2010,10,13))
.Sum(t=>t.Amount);
پاسخ: خیر!
توضیحات:
عبارت LINQ فوق در نهایت به شکل زیر ترجمه خواهد شد:
-- Region Parameters
-- @p0: DateTime [2010/10/13 12:00:00 ق.ظ]
-- EndRegion
SELECT SUM([t0].[Amount]) AS [value]
FROM [Transactions] AS [t0]
WHERE [t0].[TransactionDate] > @p0
و اتفاقا در این سیستم پس از تاریخ 2010/10/13 هیچ تراکنشی ثبت نشده است؛ بنابراین خروجی این کوئری null خواهد بود و نه صفر. همینجا است که یکی از استثناهای زیر صادر شده و ادامه‌ی برنامه با مشکل مواجه خواهد شد:
- System.InvalidOperationException: The cast to value type 'decimal' failed because the materialized value is null.
- InvalidOperationException: The null value cannot be assigned to a member with type decimal which is a non-nullable value type.

مشکل هم از اینجا ناشی می‌شود که متغییری از نوع deciaml یا int و امثال آن، مقدار دریافتی نال را نمی‌پذیرند. برای رفع این مشکل باید عبارت LINQ فوق به صورت زیر بازنویسی شود (و اهمیتی هم ندارد که Sum است یا Max یا Avg و غیره؛ در مورد بکارگیری تمام SQL Aggregate Functions در یک عبارت LINQ ، این مورد باید لحاظ گردد):
decimal amount = respository.Transactions
.Where(t=>t.TransactionDate>new DateTime(2010,10,13))
.Sum(t=>(decimal?)t.Amount)??0;

دقیقا به همین علت است که در دات نت، nullable types تعریف شده‌اند. امکان ذخیره سازی null‌ در یک متغیر برای مثال از نوع decimal وجود ندارد اما نوع decimal? (و یا Nullable<decimal> به بیانی دیگر) این قابلیت را دارد.
شاید بگوئید که در اینجا با تغییر تعریف متغیر به decimal? amount مشکل حل می‌شود، اما خیر. تعریف extension method مربوط به sum به صورت زیر است:

public static TResult Sum<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, TResult>> selector)

در این تعریف به TResult دقت نمائید؛ هم بیانگر نوع خروجی نهایی متد و هم مشخص سازنده‌ی نوع پارامتری است که خروجی Lambda Expression را تشکیل می‌دهد. به این معنا که سی شارپ، TResult را از lambda expression دریافت کرده و خروجی Sum را بر همان مبنا و نوع تشکیل می‌دهد. بنابراین برای دریافت خروجی nullable باید TResult ایی nullable را همانند مثال فوق ایجاد کنیم.

خلاصه بحث:
اگر در کدهای LINQ خود که با بانک اطلاعاتی سر و کار دارند از معادل‌های SQL Aggregate Functions استفاده کرده‌اید، آن‌ها را یافته و نکته‌ی nullable TResult فوق را به آن‌ها اعمال کنید؛ در غیر اینصورت منتظر باشید تا روزی برنامه شما به سادگی کرش کند.


مطالب
نحوه اضافه کردن قابلیت غلط گیر املایی شبیه به جستجوی گوگل توسط لوسین
پیشنیاز:
چگونه با استفاده از لوسین مطالب را ایندکس کنیم؟


مقدمه

اگر به جستجوی سایت دقت کرده باشید، قابلیتی تحت عنوان پیشنهاد «عبارات مشابه» به آن اضافه شده است:


این مورد بر اساس ماژول غلط یاب املایی لوسین تهیه شده و بسیار شبیه به "did you mean" جستجوی گوگل است. در ادامه به نحوه پیاده سازی آن خواهیم پرداخت.


کتابخانه‌های مورد نیاز

علاوه بر کتابخانه لوسین، نیاز به دریافت پروژه Contrib آن نیز می‌باشد تا بتوان از اسمبلی Lucene.Net.Contrib.SpellChecker.dll موجود در آن استفاده کرد.


نحوه کار با غلط یاب املایی لوسین

خلاصه کار با غلط یاب املایی لوسین همین چند سطر ذیل است:
var indexReader = IndexReader.Open(FSDirectory.Open(indexPath), readOnly: true);

// Create the SpellChecker
var spellChecker = new SpellChecker.Net.Search.Spell.SpellChecker(FSDirectory.Open(indexPath + "\\Spell"));

// Create SpellChecker Index
spellChecker.ClearIndex();
spellChecker.IndexDictionary(new LuceneDictionary(indexReader, "Title"));
spellChecker.IndexDictionary(new LuceneDictionary(indexReader, "Body"));

//Suggest Similar Words
var results = spellChecker.SuggestSimilar(term, number, null, null, true);
کار بر اساس یک ایندکس از پیش موجود لوسین شروع می‌شود. در اینجا فرض شده است که این ایندکس در پوشه indexPath قرار دارد.
در ادامه شیء spellChecker را آغاز خواهیم کرد. بهتر است پوشه تولید فایل‌های آن با پوشه ایندکس اصلی یکسان نباشد. اگر یکسان درنظر گرفته شود، تمام مداخل جدید به ایندکس موجود اضافه خواهند شد که می‌تواند سرعت جستجوی معمولی را کاهش دهد.
سپس کار تهیه ایندکس جدید غلط یاب املایی، شروع خواهد شد. متد spellChecker.ClearIndex، اطلاعات موجود در ایندکسی قدیمی را حذف کرده و سپس spellChecker.IndexDictionary، فیلدهایی را که نیاز داریم در تهیه غلط یاب املایی حضور داشته باشند، مشخص می‌کند.
همانطور که ملاحظه می‌کنید ایندکس جدید تهیه شده، بر اساس بانک اطلاعاتی واژه‌های موجود در ایندکس اصلی برنامه که توسط indexReader معرفی شده، تهیه می‌شود. برای نمونه در تصویر ابتدای مطلب جاری، واژه‌های پیشنهادی، واژه‌هایی هستند که پیشتر یکبار تایپ شده و در بانک اطلاعاتی برنامه موجود بوده‌اند.
و در آخر برای استفاده از امکانات تهیه شده، تنها کافی است متد spellChecker.SuggestSimilar را فراخوانی کنیم (در زمانیکه جستجوی اصلی سایت نتیجه‌ای را ارائه نداده است). حاصل لیستی از واژه‌های مشابه است.
اشتراک‌ها
پیاده سازی Etag Filter
public class ETagAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Filter = new ETagFilter(filterContext.HttpContext.Response, filterContext.RequestContext.HttpContext.Request);
    }
}

public class ETagFilter : MemoryStream
{
    private HttpResponseBase _response = null;
    private HttpRequestBase _request;
    private Stream _filter = null;

    public ETagFilter(HttpResponseBase response, HttpRequestBase request)
    {
        _response = response;
        _request = request;
        _filter = response.Filter;
    }

    private string GetToken(Stream stream)
    {
        var checksum = new byte[0];
        checksum = MD5.Create().ComputeHash(stream);
        return Convert.ToBase64String(checksum, 0, checksum.Length);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var data = new byte[count];

        Buffer.BlockCopy(buffer, offset, data, 0, count);

        var token = GetToken(new MemoryStream(data));
        var clientToken = _request.Headers["If-None-Match"];

        if (token != clientToken)
        {
            _response.AddHeader("ETag", token);
            _filter.Write(data, 0, count);
        }
        else
        {
            _response.SuppressContent = true;
            _response.StatusCode = 304;
            _response.StatusDescription = "Not Modified";
            _response.AddHeader("Content-Length", "0");
        }
    }
}
پیاده سازی Etag Filter
بازخوردهای پروژه‌ها
چند متد الحاقی SEO
سلام.
من هم چند متد الحاقی داشتم که مرتبط با SEO اند، البته حتما قابل رشد هست ...


public class SEO
{
    private const char TitleCharSeparator = '-';
    //-------------------------------------------------
    public static string GetTitle(params string[] crumbs)
    {
        var maxLenghtTitle = 60;

        var title = "";

        try
        {

            foreach (var crumb in crumbs)
            {
                title += string.Format(" {0} {1}", TitleCharSeparator, crumb);
            }
            title = title.Substring(3);
        }
        catch
        {

        }

        title = title.Substring(0, title.Length <= maxLenghtTitle ? title.Length : maxLenghtTitle).Trim(); 

        return title;
    }
    //-------------------------------------------------
    public static string GenerateMetaTag(this string pageTitle, string pageDescription)
    {
        var maxLenghtTitle = 60;
        var maxLenghtDescription = 170;

        pageTitle = pageTitle.Substring(0, pageTitle.Length <= maxLenghtTitle ? pageTitle.Length : maxLenghtTitle).Trim();
        pageDescription = pageDescription.Substring(0, pageDescription.Length <= maxLenghtDescription ? pageDescription.Length : maxLenghtDescription).Trim();


        var meta = "";

        try
        {
            meta += string.Format("<title>{0}</title>\n", pageTitle);
            meta += string.Format("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n");
            meta += string.Format("<meta charset=\"utf-8\"/>\n");
            meta += string.Format("<meta name=\"description\" content=\"{0}\"/>\n", pageDescription);
            meta += string.Format("<meta name=\"robots\" content=\"{0}\" />\n", "follow");
            meta += string.Format("<link rel=\"shortcut icon\" href=\"{0}\"/>\n", "~/cdn/images/ui/favicon.ico");
        }
        catch
        {

        }

        return meta;
    }
    //-------------------------------------------------
    public static string GenerateSlug(this string title)
    {
        var maxLenghtSlug = 45;

        string str = title.RemoveAccent().ToLower();        
str = Regex.Replace(str, @"[^a-z0-9-\u0600-\u06FF]", "-"); str = Regex.Replace(str, @"\s+", "-").Trim(); str = Regex.Replace(str, @"-+", "-"); str = str.Substring(0, str.Length <= maxLenghtSlug ? str.Length : maxLenghtSlug).Trim();

  return str; } //------------------------------------------------- private static string RemoveAccent(this string txt) { var bytes = Encoding.GetEncoding("UTF-8").GetBytes(txt); return Encoding.UTF8.GetString(bytes); } //------------------------------------------------- }


نظرات مطالب
نحوه‌ی استخراج شماره سریال سخت افزار برای تولید یک قفل سخت افزاری
می توان از این کلاس هم که در واقع بسط داده شده‌ی روش مذکور است استفاده نمود:
    public class FingerPrint
    {
        private static string fingerPrint = string.Empty;
        public static string Value()
        {
            if (string.IsNullOrEmpty(fingerPrint))
            {
                fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " +
            biosId() + "\nBASE >> " + baseId()
                    +"\nDISK >> "+ diskId() + "\nVIDEO >> " + 
                    videoId() +"\nMAC >> "+ macId());
            }
            return fingerPrint;
        }
        private static string GetHash(string s)
        {
            MD5 sec = new MD5CryptoServiceProvider();
            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] bt = enc.GetBytes(s);
            return GetHexString(sec.ComputeHash(bt));
        }
        private static string GetHexString(byte[] bt)
        {
            string s = string.Empty;
            for (int i = 0; i < bt.Length; i++)
            {
                byte b = bt[i];
                int n, n1, n2;
                n = (int)b;
                n1 = n & 15;
                n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + (int)'A')).ToString();
                else
                    s += n2.ToString();
                if (n1 > 9)
                    s += ((char)(n1 - 10 + (int)'A')).ToString();
                else
                    s += n1.ToString();
                if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }


        #region Original Device ID Getting Code
        //Return a hardware identifier
        private static string identifier
        (string wmiClass, string wmiProperty, string wmiMustBeTrue)
        {
            string result = "";
            System.Management.ManagementClass mc =
        new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                if (mo[wmiMustBeTrue].ToString() == "True")
                {
                    //Only get the first one
                    if (result == "")
                    {
                        try
                        {
                            result = mo[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            return result;
        }
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty)
        {
            string result = "";
            System.Management.ManagementClass mc =
        new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
            return result;
        }
        private static string cpuId()
        {
            //Uses first CPU identifier available in order of preference
            //Don't get all identifiers, as it is very time consuming
            string retVal = identifier("Win32_Processor", "UniqueId");
            if (retVal == "") //If no UniqueID, use ProcessorID
            {
                retVal = identifier("Win32_Processor", "ProcessorId");
                if (retVal == "") //If no ProcessorId, use Name
                {
                    retVal = identifier("Win32_Processor", "Name");
                    if (retVal == "") //If no Name, use Manufacturer
                    {
                        retVal = identifier("Win32_Processor", "Manufacturer");
                    }
                    //Add clock speed for extra security
                    retVal += identifier("Win32_Processor", "MaxClockSpeed");
                }
            }
            return retVal;
        }
        //BIOS Identifier
        private static string biosId()
        {
            return identifier("Win32_BIOS", "Manufacturer")
                + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + identifier("Win32_BIOS", "IdentificationCode")
                + identifier("Win32_BIOS", "SerialNumber")
                + identifier("Win32_BIOS", "ReleaseDate")
                + identifier("Win32_BIOS", "Version");
        }
        //Main physical hard drive ID
        private static string diskId()
        {
            return identifier("Win32_DiskDrive", "Model")
            + identifier("Win32_DiskDrive", "Manufacturer")
            + identifier("Win32_DiskDrive", "Signature")
            + identifier("Win32_DiskDrive", "TotalHeads");
        }
        //Motherboard ID
        private static string baseId()
        {
            return identifier("Win32_BaseBoard", "Model")
            + identifier("Win32_BaseBoard", "Manufacturer")
            + identifier("Win32_BaseBoard", "Name")
            + identifier("Win32_BaseBoard", "SerialNumber");
        }
        //Primary video controller ID
        private static string videoId()
        {
            return identifier("Win32_VideoController", "DriverVersion")
            + identifier("Win32_VideoController", "Name");
        }
        //First enabled network card ID
        private static string macId()
        {
            return identifier("Win32_NetworkAdapterConfiguration",
                "MACAddress", "IPEnabled");
        }
        #endregion
    }
خروجی این کلاس Hexal است و به شکل زیر قابل استفاده می‌باشد:
/// Generates a 16 byte Unique Identification code of a computer 
/// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9

var computerId = FingerPrint.Value();

نظرات مطالب
چگونگی رسیدگی به Null property در AutoMapper
public class TestModel
    {
        public byte[] MProperty { get; set; }
    }

 public class TestViewModel
    {
       public byte[] VMProperty { get; set; }
    }

class Program
    {
        static void Main(string[] args)
        {
            Mapper.CreateMap<TestModel,TestViewModel>().ForMember(tv=>tv.VMProperty,m=>m.MapFrom(t=>t.MProperty));
            TestModel tm = new TestModel();
            tm.MProperty = new byte[]  { 1, 2, 3 ,4};

            TestViewModel tvm = Mapper.Map<TestModel, TestViewModel>(tm);
            foreach (var item in tvm.VMProperty)
            {
                Console.WriteLine(item.ToString());
            }
            Console.ReadKey();
        }
    }
در صورتی که MProperty، مقدار داشته باشه مشکلی پیش نمیاد اگر هم null باشه بازم مشکلی پیش نمیاد و VMProperty برابر با null هست.
اشتراک‌ها
Replication چیست

Replication از فن آوری‌های کپی و توزیع اشیاء داده و بانک اطلاعاتی از یک بانک اطلاعاتی به دیگری و سپس همگام سازی بین پایگاه داده برای حفظ ثبات است. با استفاده از Replication شما می‌توانید اطلاعات خود را بین مکانهای متفاوت و کاربران راه دور ویا کاربران موبایل انتقال دهید 

 
Replication  چیست
نظرات مطالب
پَرباد - آموزش پیاده‌سازی پرداخت آنلاین در دات نت - آموزش پیشرفته
سلام و تشکر ا مطلب مفیدتون
می‌خواستم بدونم چطوری میشه این پروژه رو با بانک اطلاعاتی MongoDB اجرا کنم؟ برای موقعی که دسترسی به SQL Server روی سرور ندارم و بانک اطلاعاتی پروژه ای که داشتم رو با مونگو کار کردم.
نظرات مطالب
غیرمعتبر شدن کوکی‌های برنامه‌های ASP.NET Core هاست شده‌ی در IIS پس از ری‌استارت آن
-چه زمانی به بانک اطلاعاتی رجوع میکند؟
-به ازای هر درخواست به بانک اطلاعاتی رجوع میکند؟
برای سناریو هایی که تعداد کاربران زیاد، به همراه تعداد درخواست‌های زیاد وسرعت بالا مورد نیاز است، این روش بهینه میباشد؟(البته قبول دارم که باید جهت این نیاز سرور‌های اختصاصی تهیه کرد)
-سرعت کاهش پیدا نمیکند؟
بهتر نیست از FileSystem بهره برد؟
نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 2 - به روز رسانی ساختار بانک اطلاعاتی
بعد از انجام تغییرات در مدل‌ها و نگاشت‌های آن‌ها، نیاز است فایل _01-add_migrations.cmd را اجرا کنید تا نحوه‌ی اعمال این تغییرات به بانک اطلاعاتی تولید شود. سپس یا فایل _02-update_db.cmd را اجرا کنید تا این تغییرات به بانک اطلاعاتی اعمال شوند، یا قطعه کد Database.Migrate هم دقیقا کار همین اسکریپت دوم را انجام می‌دهد.