Thursday, 2 May 2024

Difference between IEnumerable,IQueryable VS List

 First the difference between List<T>, IEnumerable<T> and IQueryable<T>.

 The content of List<T> will always be loaded into memory, because it uses an array in the background.


The content of IEnumerable<T> will only load the requested item into the memory. Compiler sets up a state machine during compiling a method with IEnumerable<T> that has a yield return T. So only one item at a time will be loaded into memory in this case.


IQueryable<T> is "special" version of IEnumerable<T>. Specifically designed to query data sources, and implemented by data providers. Like EF, NHibernate. So when you tell EF to fetch the data with .ToListAsync<T>() EF will only then go the database and execute the generated query. See the docs for more info about IQueryable<T>.

Thursday, 28 December 2023

C# Enum Value and Display name Extension

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Web;

namespace Helper.Extensions
{
    public static class EnumExtensions
    {
        public static string GetEnumValue(this Enum enumValue)
        {
            var type = enumValue.GetType();
            var info = type.GetField(enumValue.ToString());
            if (info == null) return string.Empty;

            var da = (EnumMemberAttribute[])
                    (info.GetCustomAttributes(typeof(EnumMemberAttribute), false));

            if (da.Length > 0)
                return da[0].Value;
            else
                return string.Empty;
        }

        public static string GetDisplayName(this Enum enumValue)
        {
            return enumValue.GetType()
                            .GetMember(enumValue.ToString())
                            .First()
                            .GetCustomAttribute<DisplayAttribute>()
                            .GetName();
        }

    }
}

Friday, 4 August 2023

C# simple example for recursive call

using System;
class HelloWorld {
  static void Main() {
      var result=print(0);
    Console.WriteLine(result);
  }
  public static string print(int count)
  {
      return print2(count);
  }
  public static string print2(int count)
  {
      if(count <= 2)
      {
          Console.WriteLine(count);
          count++;
          //recursive call upto 3count
          return print(count);
      }
     
      return "Recursive final return";
  }
}

//output like below
0
1
2
Recursive final return

Friday, 21 July 2023

Mapster over AutoMapper for mapping objects in c# Crud

1.Add Mapster packages from NuGet

<package id="Mapster" version="7.3.0" targetFramework="net48" />
<package id="Mapster.Core" version="1.2.0" targetFramework="net48" />

2.Create Source class

//Source or DTO
public class TempCacheDto
    {
        public int Id { get; set; }

        public string SerialNumber { get; set; }
    }

3.Create Destination class

//Destination or Entity Db object
public class TempCache
    {
        public int Id { get; set; }

        public string SerialNumber { get; set; }
    }

4.Create Service or repository class where mapping required to convert Dto to Enity object.

Simple Save and Retrieve example below for using mapster and entity framework.


using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TempCache.Repositories
{
    public class TempCacheRepository
    {
//save data from dto model to entity using mapster        
        public bool Save(TempCacheModel bcTempCache)
        {
            using (var context = new DbContext())
            {

                if (bcTempCache.Id == 0)
                {
                    TempCache entity = bcTempCache.Adapt<TempCache>();
                    context.TempCaches.Add(entity);
                }
                else
                {
                    TempCache exist = context.TempCaches
                                        .FirstOrDefault(x => x.Id == bcTempCache.Id);
                    if (exist != null)
                    {
                        exist = bcTempCache.Adapt<TempCacheModel, TempCache>(exist);
                    }
                    else
                    {
                        return false;
                    }
                }
                context.SaveChanges();
                return true;
            }
        }
//get list from Db and retun as dto list using mapster
        public List<TempCacheModel> TempCaches()
        {
            using (var context = new DbContext())
            {
                return context.TempCaches.ToList().Adapt<List<TempCacheModel>>();
            }
        }
//get list from Db and retun as dto list using mapster        
        public TempCacheModel GetById(int id)
        {
            using (var context = new DbContext())
            {
                return context.TempCaches.FirstOrDefault(x=>x.Id==slNo)?
                        .Adapt<TempCacheModel>();
            }
        }
    }
}

Why Mapster over Auto mapper

MethodMeanStdDevErrorGen 0Gen 1Gen 2Allocated
'Mapster 6.0.0'108.59 ms1.198 ms1.811 ms31000.0000--124.36 MB
'Mapster 6.0.0 (Roslyn)'38.45 ms0.494 ms0.830 ms31142.8571--124.36 MB
'Mapster 6.0.0 (FEC)'37.03 ms0.281 ms0.472 ms29642.8571--118.26 MB
'Mapster 6.0.0 (Codegen)'34.16 ms0.209 ms0.316 ms31133.3333--124.36 MB
'ExpressMapper 1.9.1'205.78 ms5.357 ms8.098 ms59000.0000--236.51 MB
'AutoMapper 10.0.0'420.97 ms23.266 ms35.174 ms87000.0000--350.95 MB