kandi background
Explore Kits

Dapper | Dapper a simple object mapper for .Net | SQL Database library

 by   DapperLib C# Version: Current License: Non-SPDX

 by   DapperLib C# Version: Current License: Non-SPDX

Download this library from

kandi X-RAY | Dapper Summary

Dapper is a C# library typically used in Database, SQL Database applications. Dapper has no bugs, it has no vulnerabilities and it has medium support. However Dapper has a Non-SPDX License. You can download it from GitHub.
Dapper - a simple object mapper for .Net
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • Dapper has a medium active ecosystem.
  • It has 14058 star(s) with 3403 fork(s). There are 988 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 272 open issues and 771 have been closed. On average issues are closed in 446 days. There are 36 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of Dapper is current.
Dapper Support
Best in #SQL Database
Average in #SQL Database
Dapper Support
Best in #SQL Database
Average in #SQL Database

quality kandi Quality

  • Dapper has 0 bugs and 0 code smells.
Dapper Quality
Best in #SQL Database
Average in #SQL Database
Dapper Quality
Best in #SQL Database
Average in #SQL Database

securitySecurity

  • Dapper has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • Dapper code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
Dapper Security
Best in #SQL Database
Average in #SQL Database
Dapper Security
Best in #SQL Database
Average in #SQL Database

license License

  • Dapper has a Non-SPDX License.
  • Non-SPDX licenses can be open source with a non SPDX compliant license, or non open source licenses, and you need to review them closely before use.
Dapper License
Best in #SQL Database
Average in #SQL Database
Dapper License
Best in #SQL Database
Average in #SQL Database

buildReuse

  • Dapper releases are not available. You will need to build from source code and install.
  • It has 30 lines of code, 0 functions and 149 files.
  • It has low code complexity. Code complexity directly impacts maintainability of the code.
Dapper Reuse
Best in #SQL Database
Average in #SQL Database
Dapper Reuse
Best in #SQL Database
Average in #SQL Database
Top functions reviewed by kandi - BETA

Coming Soon for all Libraries!

Currently covering the most popular Java, JavaScript and Python libraries. See a SAMPLE HERE.
kandi's functional review helps you automatically verify the functionalities of the libraries and avoid rework.

Dapper Key Features

Dapper - a simple object mapper for .Net

Creating a specific dataset with LINQ

copy iconCopydownload iconDownload
private List<AttendanceViewModel> GetAttendanceViewModels((whatever type 'results' is goes here) {type} results)
{
    var output = new List<AttendanceViewModel>();
    foreach(result in results)
    {
        var totalTime = CalculateTotalTimeForOneDay(result);
        var breakTime = CalculateBreakTime(result);
        result.TotalTime = totalTime;
        result.BreakTime = breakTime;
    }
    return output.GroupBy(u => u.UserId)
}
-----------------------
List<AttendaceViewModel> resultList = result
    .GroupBy(a => (a.UserId, a.FullName, DateIn: a.DateTimeUtcIn.Date, a.DayOfTheWeek, a.LocationId, a.StatusId))
    .Select(ag => new AttendaceViewModel
    {
        UserId = ag.Key.UserId,
        FullName = ag.Key.FullName,
        Date = ag.Key.DateIn.ToString(),
        DayOfTheWeek = ag.Key.DayOfTheWeek,
        Locations = ag.Key.LocationId.ToString(),
        Status = ag.Key.StatusId.ToString(),
        TotalTime = new TimeSpan(ag.Sum(a => (a.DateTimeUtcOut - a.DateTimeUtcIn).Ticks)).ToString(),
        TimesInAndOut = ag.Select(a => new Time { DateTimeUtcIn = a.DateTimeUtcIn, DateTimeUtcOut = a.DateTimeUtcOut }).ToList(),
        BreakTime = CalcBreaks(ag.Select(a => (a.DateTimeUtcIn, a.DateTimeUtcOut))).ToString()
    })
    .ToList();
private static TimeSpan CalcBreaks(IEnumerable<(DateTime inTime, DateTime outTime)> times)
{
    if (!times.Skip(1).Any())
        return TimeSpan.Zero;

    TimeSpan totalBreakTime = TimeSpan.Zero;
    TimeSpan lastLeaveTime = times.First().outTime.TimeOfDay;

    foreach(var attendanceTime in times.OrderBy(at => at.inTime).ThenBy(at => at.outTime).Skip(1))
    {
        TimeSpan breakTime = attendanceTime.inTime.TimeOfDay - lastLeaveTime;
        totalBreakTime += breakTime;
        lastLeaveTime = attendanceTime.outTime.TimeOfDay;
    }

    return totalBreakTime;
}
-----------------------
List<AttendaceViewModel> resultList = result
    .GroupBy(a => (a.UserId, a.FullName, DateIn: a.DateTimeUtcIn.Date, a.DayOfTheWeek, a.LocationId, a.StatusId))
    .Select(ag => new AttendaceViewModel
    {
        UserId = ag.Key.UserId,
        FullName = ag.Key.FullName,
        Date = ag.Key.DateIn.ToString(),
        DayOfTheWeek = ag.Key.DayOfTheWeek,
        Locations = ag.Key.LocationId.ToString(),
        Status = ag.Key.StatusId.ToString(),
        TotalTime = new TimeSpan(ag.Sum(a => (a.DateTimeUtcOut - a.DateTimeUtcIn).Ticks)).ToString(),
        TimesInAndOut = ag.Select(a => new Time { DateTimeUtcIn = a.DateTimeUtcIn, DateTimeUtcOut = a.DateTimeUtcOut }).ToList(),
        BreakTime = CalcBreaks(ag.Select(a => (a.DateTimeUtcIn, a.DateTimeUtcOut))).ToString()
    })
    .ToList();
private static TimeSpan CalcBreaks(IEnumerable<(DateTime inTime, DateTime outTime)> times)
{
    if (!times.Skip(1).Any())
        return TimeSpan.Zero;

    TimeSpan totalBreakTime = TimeSpan.Zero;
    TimeSpan lastLeaveTime = times.First().outTime.TimeOfDay;

    foreach(var attendanceTime in times.OrderBy(at => at.inTime).ThenBy(at => at.outTime).Skip(1))
    {
        TimeSpan breakTime = attendanceTime.inTime.TimeOfDay - lastLeaveTime;
        totalBreakTime += breakTime;
        lastLeaveTime = attendanceTime.outTime.TimeOfDay;
    }

    return totalBreakTime;
}

Why is an Azure Function on .NET 6 looking for System.ComponentModel Version 6.0.0.0?

copy iconCopydownload iconDownload
 dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 5.0.0-rc.2.20475.6

How to setup .NET 6 with Dapper Identity and Discord Login

copy iconCopydownload iconDownload
    /// <summary>
    /// Gets the external login information for the current login, as an asynchronous operation.
    /// </summary>
    /// <param name="expectedXsrf">Flag indication whether a Cross Site Request Forgery token was expected in the current request.</param>
    /// <returns>The task object representing the asynchronous operation containing the <see name="ExternalLoginInfo"/>
    /// for the sign-in attempt.</returns>
    public virtual async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
    {
        var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme);
        var items = auth?.Properties?.Items;
        if (auth?.Principal == null || items == null || !items.ContainsKey(LoginProviderKey))
        {
            // What cases can lead us here?
            // * The authentication was unsuccessful maybe due to
            //   - Login cancellation
            //   - Project not running on a secured environment (https)
            //   - SignInScheme property of auth options not
            //     equal to IdentityConstants.ExternalScheme
            return null;
        }

        if (expectedXsrf != null)
        {
            // It is important to note that XsrfKey is a constant
            // declared above in this class whose value is "XsrfId".
            if (!items.ContainsKey(XsrfKey))
            {
              // What cases can lead us here?
              // * You passed an argument for expectedXsrf but
              //   the initialized key-value pairs does not contain
              //   any key for XsrfKey ("XsrfId").
              // In your case the below is wrong:
              // properties.Items.Add("XsrfKey", "Test"); <= remove
              // Pass the value as 3rd parameter in
              // "ConfigureExternalAuthenticationProperties" method call instead
              // _signInService.ConfigureExternalAuthenticationProperties(provider, redirectUrl, "Test")
                return null;
            }
            var userId = items[XsrfKey] as string;
            if (userId != expectedXsrf)
            {
              // What cases can lead us here?
              // * The argument passed for expectedXsrf does not
              //   match the value of initialized key-value pair
              //   for XsrfKey ("XsrfId").
              // Ensure "Test" should go with "XsrfId" as key
              // by passing the value as 3rd parameter in
              // "ConfigureExternalAuthenticationProperties" method call instead.
                return null;
            }
        }

        var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
        var provider = items[LoginProviderKey] as string;
        if (providerKey == null || provider == null)
        {
            return null;
        }

        var providerDisplayName = (await GetExternalAuthenticationSchemesAsync()).FirstOrDefault(p => p.Name == provider)?.DisplayName
                                  ?? provider;
        return new ExternalLoginInfo(auth.Principal, provider, providerKey, providerDisplayName)
        {
            AuthenticationTokens = auth.Properties.GetTokens()
        };
    }

Is there some way with dapper object in object to load in sfdatagrid?

copy iconCopydownload iconDownload
public class Roles
{
    public int id {get;set;}
    public string name {get;set;}

}
public List<Users> GetUsers() { 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(Helper.CnnVal("db2021"))) { 
        var sql = @"SELECT A.*, B.* FROM users A INNER JOIN Roles B on B.id = A.roleID"; 
        var result = connection.Query<Users,Roles,Users>(sql, (a, b) => 
        { 
             a.role = b; 
             return a; 
        }).ToList(); 
        return result; 
   } 
}


List<Users> users = GetUsers(); 
sfDataGrid1.DataSource = users;
public class UsersViewModel
{
    public int id { get; set; }
    public string name { get; set; }
    public string email { get; set; }
    public int roleid {get;set;}
    public string rolename {get;set;}
}
public List<Users> GetUsers() 
{ 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(....))
    { 
        var sql = @"SELECT A.*, B.name as rolename 
                    FROM users A INNER JOIN Roles B 
                                 ON B.id = A.roleID"; 
        var result = connection.Query<UsersViewModel>(sql).ToList(); 
        return result; 
   } 
}
-----------------------
public class Roles
{
    public int id {get;set;}
    public string name {get;set;}

}
public List<Users> GetUsers() { 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(Helper.CnnVal("db2021"))) { 
        var sql = @"SELECT A.*, B.* FROM users A INNER JOIN Roles B on B.id = A.roleID"; 
        var result = connection.Query<Users,Roles,Users>(sql, (a, b) => 
        { 
             a.role = b; 
             return a; 
        }).ToList(); 
        return result; 
   } 
}


List<Users> users = GetUsers(); 
sfDataGrid1.DataSource = users;
public class UsersViewModel
{
    public int id { get; set; }
    public string name { get; set; }
    public string email { get; set; }
    public int roleid {get;set;}
    public string rolename {get;set;}
}
public List<Users> GetUsers() 
{ 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(....))
    { 
        var sql = @"SELECT A.*, B.name as rolename 
                    FROM users A INNER JOIN Roles B 
                                 ON B.id = A.roleID"; 
        var result = connection.Query<UsersViewModel>(sql).ToList(); 
        return result; 
   } 
}
-----------------------
public class Roles
{
    public int id {get;set;}
    public string name {get;set;}

}
public List<Users> GetUsers() { 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(Helper.CnnVal("db2021"))) { 
        var sql = @"SELECT A.*, B.* FROM users A INNER JOIN Roles B on B.id = A.roleID"; 
        var result = connection.Query<Users,Roles,Users>(sql, (a, b) => 
        { 
             a.role = b; 
             return a; 
        }).ToList(); 
        return result; 
   } 
}


List<Users> users = GetUsers(); 
sfDataGrid1.DataSource = users;
public class UsersViewModel
{
    public int id { get; set; }
    public string name { get; set; }
    public string email { get; set; }
    public int roleid {get;set;}
    public string rolename {get;set;}
}
public List<Users> GetUsers() 
{ 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(....))
    { 
        var sql = @"SELECT A.*, B.name as rolename 
                    FROM users A INNER JOIN Roles B 
                                 ON B.id = A.roleID"; 
        var result = connection.Query<UsersViewModel>(sql).ToList(); 
        return result; 
   } 
}
-----------------------
public class Roles
{
    public int id {get;set;}
    public string name {get;set;}

}
public List<Users> GetUsers() { 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(Helper.CnnVal("db2021"))) { 
        var sql = @"SELECT A.*, B.* FROM users A INNER JOIN Roles B on B.id = A.roleID"; 
        var result = connection.Query<Users,Roles,Users>(sql, (a, b) => 
        { 
             a.role = b; 
             return a; 
        }).ToList(); 
        return result; 
   } 
}


List<Users> users = GetUsers(); 
sfDataGrid1.DataSource = users;
public class UsersViewModel
{
    public int id { get; set; }
    public string name { get; set; }
    public string email { get; set; }
    public int roleid {get;set;}
    public string rolename {get;set;}
}
public List<Users> GetUsers() 
{ 
    using (IDbConnection connection = new MySql.Data.MySqlClient.MySqlConnection(....))
    { 
        var sql = @"SELECT A.*, B.name as rolename 
                    FROM users A INNER JOIN Roles B 
                                 ON B.id = A.roleID"; 
        var result = connection.Query<UsersViewModel>(sql).ToList(); 
        return result; 
   } 
}

Dapper Exception - &quot;The ConnectionString property has not been initialized&quot; when 'buffered' is 'false'

copy iconCopydownload iconDownload
using IDbConnection db = new SqlConnection(connectionString);
foreach (var row in db.Query<T>(sql, parameters, commandType: commandType, commandTimeout: COMMAND_TIMEOUT, buffered: false)
{
    yield return row;
}

Why does a dapper query fail and a ado call not?

copy iconCopydownload iconDownload
db.Open();
await db.OpenAsync().ConfigureAwait(false);
private IDbConnection _db;
public IDbConnection DbConnection
   => _db ?? CreateOpenConnection();
private IDbConnection CreateOpenConnection()
{
    if (_db is null)
    {
        _db = new SqlConnection(_connectionstring);
        _db.Open();
    }
    return _db;
}
-----------------------
db.Open();
await db.OpenAsync().ConfigureAwait(false);
private IDbConnection _db;
public IDbConnection DbConnection
   => _db ?? CreateOpenConnection();
private IDbConnection CreateOpenConnection()
{
    if (_db is null)
    {
        _db = new SqlConnection(_connectionstring);
        _db.Open();
    }
    return _db;
}
-----------------------
db.Open();
await db.OpenAsync().ConfigureAwait(false);
private IDbConnection _db;
public IDbConnection DbConnection
   => _db ?? CreateOpenConnection();
private IDbConnection CreateOpenConnection()
{
    if (_db is null)
    {
        _db = new SqlConnection(_connectionstring);
        _db.Open();
    }
    return _db;
}

How do I add multiple &quot;WHERE conditionA OR conditionB OR conditionC&quot; in SQL parameter?

copy iconCopydownload iconDownload
SELECT *
FROM device WHERE site_id = @SiteId
AND (device_type_id = @DeviceTypeID1
    OR device_type_id = @DeviceTypeID2
    OR device_type_id = @DeviceTypeID3)
ORDER BY site_id
OFFSET @RowsOffset ROWS
FETCH NEXT @PageSize ROWS ONLY

var param = new
{
    SiteId = siteId,
    RowsOffset = rowsOffset,
    PageSize = pageSize,
    DeviceTypeID1 = deviceTypeID1,
    DeviceTypeID2 = deviceTypeID2,
    DeviceTypeID3 = deviceTypeID3
};
SELECT *
FROM device WHERE site_id = @SiteId
AND device_type_id IN @DeviceTypeIDs
ORDER BY site_id
OFFSET @RowsOffset ROWS
FETCH NEXT @PageSize ROWS ONLY

var param = new
{
    SiteId = siteId,
    RowsOffset = rowsOffset,
    PageSize = pageSize,
    DeviceTypeIDs = deviceTypes
};
-----------------------
SELECT *
FROM device WHERE site_id = @SiteId
AND (device_type_id = @DeviceTypeID1
    OR device_type_id = @DeviceTypeID2
    OR device_type_id = @DeviceTypeID3)
ORDER BY site_id
OFFSET @RowsOffset ROWS
FETCH NEXT @PageSize ROWS ONLY

var param = new
{
    SiteId = siteId,
    RowsOffset = rowsOffset,
    PageSize = pageSize,
    DeviceTypeID1 = deviceTypeID1,
    DeviceTypeID2 = deviceTypeID2,
    DeviceTypeID3 = deviceTypeID3
};
SELECT *
FROM device WHERE site_id = @SiteId
AND device_type_id IN @DeviceTypeIDs
ORDER BY site_id
OFFSET @RowsOffset ROWS
FETCH NEXT @PageSize ROWS ONLY

var param = new
{
    SiteId = siteId,
    RowsOffset = rowsOffset,
    PageSize = pageSize,
    DeviceTypeIDs = deviceTypes
};

How to specify a Schema while mapping with DapperExtensions?

copy iconCopydownload iconDownload
public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }
}

public sealed class CustomerMapper : ClassMapper<Customer>
{
    public CustomerMapper()
    {
        Schema("dbo");
        Table("Customer");
        Map(x => x.CustomerID).Key(KeyType.Identity);
        AutoMap();
    }
}
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });
-----------------------
public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }
}

public sealed class CustomerMapper : ClassMapper<Customer>
{
    public CustomerMapper()
    {
        Schema("dbo");
        Table("Customer");
        Map(x => x.CustomerID).Key(KeyType.Identity);
        AutoMap();
    }
}
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });

How to customize SQL query according to GraphQL request using HotChocolate and Dapper?

copy iconCopydownload iconDownload
public static class IResolverContextSelectionExtensions
{
    /// <summary>
    /// Similar to CollectFields in v10, this uses GetSelections but safely validates that the current context
    ///     has selections before returning them, it will safely return null if unable to do so.
    /// This is a variation of the helper method provided by HotChocolate team here: 
    ///     https://github.com/ChilliCream/hotchocolate/issues/1527#issuecomment-596175928
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static IReadOnlyList<PreProcessingSelection> GetPreProcessingSelections(this IResolverContext? context)
    {
        if (context == null)
            return null!;

        var selectionResults = new List<PreProcessingSelection>();

        var selections = GatherChildSelections(context!);
        if (selections.Any())
        {
            //BBernard
            //Determine if the Selection is for a Connection, and dive deeper to get the real
            //  selections from the node {} field.
            var lookup = selections.ToLookup(s => s.SelectionName.ToString().ToLower());

            //Handle paging cases; current Node is a Connection so we have to look for selections inside
            //  ->edges->nodes, or inside the ->nodes (shortcut per Relay spec); both of which may exist(?)
            if (lookup.Contains(SelectionNodeName.Nodes) || lookup.Contains(SelectionNodeName.Edges) || lookup.Contains(SelectionNodeName.Items))
            {
                //Cursor & Offset Paging are mutually exclusive so this small optimization prevents unnecessary processing...
                var searchOffsetPagingEnabled = true;

                //CURSOR PAGING SUPPORT - results are in either a 'Nodes' or 'Edges' Node!
                //NOTE: nodes and edges are not mutually exclusive per Relay spec so
                //          we gather from all if they are defined...
                if (lookup.Contains(SelectionNodeName.Nodes))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Nodes].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);

                    searchOffsetPagingEnabled = false;
                }

                if (lookup.Contains(SelectionNodeName.Edges))
                {
                    var edgesSelectionField = lookup[SelectionNodeName.Edges].FirstOrDefault();
                    //If Edges are specified then Selections are actually inside a nested 'Node' (singular, not plural) that we need to traverse...
                    var nodesSelectionField = FindChildSelectionByName(context, SelectionNodeName.EdgeNode, edgesSelectionField);
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                    
                    searchOffsetPagingEnabled = false;
                }

                //OFFSET PAGING SUPPORT - results are in an 'Items' Node!
                if (searchOffsetPagingEnabled && lookup.Contains(SelectionNodeName.Items))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Items].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                }
            }
            //Handle Non-paging cases; current Node is an Entity...
            else
            {
                selectionResults.AddRange(selections);
            }
        }

        return selectionResults;
    }

    /// <summary>
    /// Find the selection that matches the specified name.
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <param name="selectionFieldName"></param>
    /// <returns></returns>
    private static PreProcessingSelection FindChildSelectionByName(IResolverContext? context, string selectionFieldName, PreProcessingSelection? baseSelection)
    {
        if (context == null)
            return null!;

        var childSelections = GatherChildSelections(context!, baseSelection);
        var resultSelection = childSelections?.FirstOrDefault(
            s => s.SelectionName.Equals(selectionFieldName, StringComparison.OrdinalIgnoreCase)
        )!;

        return resultSelection!;
    }

    /// <summary>
    /// Gather all child selections of the specified Selection
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <returns></returns>
    private static List<PreProcessingSelection> GatherChildSelections(IResolverContext? context, PreProcessingSelection? baseSelection = null)
    {
        if (context == null)
            return null!;

        var gathered = new List<PreProcessingSelection>();

        //Initialize the optional base field selection if specified...
        var baseFieldSelection = baseSelection?.GraphQLFieldSelection;
        
        //Dynamically support re-basing to the specified baseSelection or fallback to current Context.Field
        var field = baseFieldSelection?.Field ?? context.Field;

        //Initialize the optional SelectionSet to rebase processing as the root for GetSelections()
        //  if specified (but is optional & null safe)...
        SelectionSetNode? baseSelectionSetNode = baseFieldSelection is ISelection baseISelection
            ? baseISelection.SelectionSet
            : null!;

        //Get all possible ObjectType(s); InterfaceTypes & UnionTypes will have more than one...
        var objectTypes = GetObjectTypesSafely(field.Type, context.Schema);

        //Map all object types into PreProcessingSelection (adapter classes)...
        foreach (var objectType in objectTypes)
        {
            //Now we can process the ObjectType with the correct context (selectionSet may be null resulting
            //  in default behavior for current field.
            var childSelections = context.GetSelections(objectType, baseSelectionSetNode);
            var preprocessSelections = childSelections.Select(s => new PreProcessingSelection(objectType, s));
            gathered.AddRange(preprocessSelections);
        }

        return gathered;
    }

    /// <summary>
    /// ObjectType resolver function to get the current object type enhanced with support
    /// for InterfaceTypes & UnionTypes; initially modeled after from HotChocolate source:
    /// HotChocolate.Data -> SelectionVisitor`1.cs
    /// </summary>
    /// <param name="type"></param>
    /// <param name="objectType"></param>
    /// <param name="schema"></param>
    /// <returns></returns>
    private static List<ObjectType> GetObjectTypesSafely(IType type, ISchema schema)
    {
        var results = new List<ObjectType>();
        switch (type)
        {
            case NonNullType nonNullType:
                results.AddRange(GetObjectTypesSafely(nonNullType.NamedType(), schema));
                break;
            case ObjectType objType:
                results.Add(objType);
                break;
            case ListType listType:
                results.AddRange(GetObjectTypesSafely(listType.InnerType(), schema));
                break;
            case InterfaceType interfaceType:
                var possibleInterfaceTypes = schema.GetPossibleTypes(interfaceType);
                var objectTypesForInterface = possibleInterfaceTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForInterface);
                break;
            case UnionType unionType:
                var possibleUnionTypes = schema.GetPossibleTypes(unionType);
                var objectTypesForUnion = possibleUnionTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForUnion);
                break;
        }

        return results;
    }
}
    [GraphQLName("products")]
    public async Task<IEnumerable<Products> GetProductsByIdAsync(
        IResolverContext context,
        [Service] ProductsService productsService,
        CancellationToken cancellationToken,
        int id
    )
    {
        //Per the Annotation based Resolver signature here HC will inject the 'id' argument for us!
        //Otherwise this is just normal Resolver stuff...
        var productId = id;

        //Also you could get the argument from the IResolverContext...
        var productId = context.Argument<int>("id");. . . 
    }
public static class IResolverContextSortingExtensions
{
    /// <summary>
    /// Safely process the GraphQL context to retrieve the Order argument;
    /// matches the default name used by HotChocolate Sorting middleware (order: {{field1}: ASC, {field2}: DESC).
    /// Will return null if the order arguments/info is not available.
    /// </summary>
    /// <returns></returns>
    public static List<ISortOrderField>? GetSortingArgsSafely(this IResolverContext context, string sortOrderArgName = null!)
    {
        var results = new List<ISortOrderField>();

        //Unfortunately the Try/Catch is required to make this safe for easier coding when the argument is not specified,
        //  because the ResolverContext doesn't expose a method to check if an argument exists...
        try
        {
            var sortArgName = sortOrderArgName ?? SortConventionDefinition.DefaultArgumentName;

            //Get Sort Argument Fields and current Values...
            //NOTE: In order to correctly be able to Map names from GraphQL Schema to property/member names
            //      we need to get both the Fields (Schema) and the current order values...
            //NOTE: Not all Queries have Fields (e.g. no Selections, just a literal result), so .Field may
            //      throw internal NullReferenceException, hence we have the wrapper Try/Catch.
            IInputField sortArgField = context.Field.Arguments[sortArgName];
            ObjectValueNode sortArgValue = context.ArgumentLiteral<ObjectValueNode>(sortArgName);

            //Validate that we have some sort args specified and that the Type is correct (ListType of SortInputType values)...
            //NOTE: The Following processing logic was adapted from 'QueryableSortProvider' implementation in HotChocolate.Data core.
            //FIX: The types changed in v11.0.1/v11.0.2 the Sort Field types need to be checked with IsNull() method, and
            //      then against NonNullType.NamedType() is ISortInputType instead.
            if (!sortArgValue.IsNull()
                && sortArgField.Type is ListType lt
                && lt.ElementType is NonNullType nn 
                && nn.NamedType() is ISortInputType sortInputType)
            {
                //Create a Lookup for the Fields...
                var sortFieldLookup = sortInputType.Fields.OfType<SortField>().ToLookup(f => f.Name.ToString().ToLower());

                //Now only process the values provided, but initialize with the corresponding Field (metadata) for each value...
                var sortOrderFields = sortArgValue.Fields.Select(
                    f => new SortOrderField(
                        sortFieldLookup[f.Name.ToString().ToLower()].FirstOrDefault(), 
                        f.Value.ToString()
                    )
                );

                results.AddRange(sortOrderFields);
            }

            return results;
        }
        catch
        {
            //Always safely return at least an Empty List to help minimize Null Reference issues.
            return results;
        }
    }
}
-----------------------
public static class IResolverContextSelectionExtensions
{
    /// <summary>
    /// Similar to CollectFields in v10, this uses GetSelections but safely validates that the current context
    ///     has selections before returning them, it will safely return null if unable to do so.
    /// This is a variation of the helper method provided by HotChocolate team here: 
    ///     https://github.com/ChilliCream/hotchocolate/issues/1527#issuecomment-596175928
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static IReadOnlyList<PreProcessingSelection> GetPreProcessingSelections(this IResolverContext? context)
    {
        if (context == null)
            return null!;

        var selectionResults = new List<PreProcessingSelection>();

        var selections = GatherChildSelections(context!);
        if (selections.Any())
        {
            //BBernard
            //Determine if the Selection is for a Connection, and dive deeper to get the real
            //  selections from the node {} field.
            var lookup = selections.ToLookup(s => s.SelectionName.ToString().ToLower());

            //Handle paging cases; current Node is a Connection so we have to look for selections inside
            //  ->edges->nodes, or inside the ->nodes (shortcut per Relay spec); both of which may exist(?)
            if (lookup.Contains(SelectionNodeName.Nodes) || lookup.Contains(SelectionNodeName.Edges) || lookup.Contains(SelectionNodeName.Items))
            {
                //Cursor & Offset Paging are mutually exclusive so this small optimization prevents unnecessary processing...
                var searchOffsetPagingEnabled = true;

                //CURSOR PAGING SUPPORT - results are in either a 'Nodes' or 'Edges' Node!
                //NOTE: nodes and edges are not mutually exclusive per Relay spec so
                //          we gather from all if they are defined...
                if (lookup.Contains(SelectionNodeName.Nodes))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Nodes].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);

                    searchOffsetPagingEnabled = false;
                }

                if (lookup.Contains(SelectionNodeName.Edges))
                {
                    var edgesSelectionField = lookup[SelectionNodeName.Edges].FirstOrDefault();
                    //If Edges are specified then Selections are actually inside a nested 'Node' (singular, not plural) that we need to traverse...
                    var nodesSelectionField = FindChildSelectionByName(context, SelectionNodeName.EdgeNode, edgesSelectionField);
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                    
                    searchOffsetPagingEnabled = false;
                }

                //OFFSET PAGING SUPPORT - results are in an 'Items' Node!
                if (searchOffsetPagingEnabled && lookup.Contains(SelectionNodeName.Items))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Items].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                }
            }
            //Handle Non-paging cases; current Node is an Entity...
            else
            {
                selectionResults.AddRange(selections);
            }
        }

        return selectionResults;
    }

    /// <summary>
    /// Find the selection that matches the specified name.
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <param name="selectionFieldName"></param>
    /// <returns></returns>
    private static PreProcessingSelection FindChildSelectionByName(IResolverContext? context, string selectionFieldName, PreProcessingSelection? baseSelection)
    {
        if (context == null)
            return null!;

        var childSelections = GatherChildSelections(context!, baseSelection);
        var resultSelection = childSelections?.FirstOrDefault(
            s => s.SelectionName.Equals(selectionFieldName, StringComparison.OrdinalIgnoreCase)
        )!;

        return resultSelection!;
    }

    /// <summary>
    /// Gather all child selections of the specified Selection
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <returns></returns>
    private static List<PreProcessingSelection> GatherChildSelections(IResolverContext? context, PreProcessingSelection? baseSelection = null)
    {
        if (context == null)
            return null!;

        var gathered = new List<PreProcessingSelection>();

        //Initialize the optional base field selection if specified...
        var baseFieldSelection = baseSelection?.GraphQLFieldSelection;
        
        //Dynamically support re-basing to the specified baseSelection or fallback to current Context.Field
        var field = baseFieldSelection?.Field ?? context.Field;

        //Initialize the optional SelectionSet to rebase processing as the root for GetSelections()
        //  if specified (but is optional & null safe)...
        SelectionSetNode? baseSelectionSetNode = baseFieldSelection is ISelection baseISelection
            ? baseISelection.SelectionSet
            : null!;

        //Get all possible ObjectType(s); InterfaceTypes & UnionTypes will have more than one...
        var objectTypes = GetObjectTypesSafely(field.Type, context.Schema);

        //Map all object types into PreProcessingSelection (adapter classes)...
        foreach (var objectType in objectTypes)
        {
            //Now we can process the ObjectType with the correct context (selectionSet may be null resulting
            //  in default behavior for current field.
            var childSelections = context.GetSelections(objectType, baseSelectionSetNode);
            var preprocessSelections = childSelections.Select(s => new PreProcessingSelection(objectType, s));
            gathered.AddRange(preprocessSelections);
        }

        return gathered;
    }

    /// <summary>
    /// ObjectType resolver function to get the current object type enhanced with support
    /// for InterfaceTypes & UnionTypes; initially modeled after from HotChocolate source:
    /// HotChocolate.Data -> SelectionVisitor`1.cs
    /// </summary>
    /// <param name="type"></param>
    /// <param name="objectType"></param>
    /// <param name="schema"></param>
    /// <returns></returns>
    private static List<ObjectType> GetObjectTypesSafely(IType type, ISchema schema)
    {
        var results = new List<ObjectType>();
        switch (type)
        {
            case NonNullType nonNullType:
                results.AddRange(GetObjectTypesSafely(nonNullType.NamedType(), schema));
                break;
            case ObjectType objType:
                results.Add(objType);
                break;
            case ListType listType:
                results.AddRange(GetObjectTypesSafely(listType.InnerType(), schema));
                break;
            case InterfaceType interfaceType:
                var possibleInterfaceTypes = schema.GetPossibleTypes(interfaceType);
                var objectTypesForInterface = possibleInterfaceTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForInterface);
                break;
            case UnionType unionType:
                var possibleUnionTypes = schema.GetPossibleTypes(unionType);
                var objectTypesForUnion = possibleUnionTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForUnion);
                break;
        }

        return results;
    }
}
    [GraphQLName("products")]
    public async Task<IEnumerable<Products> GetProductsByIdAsync(
        IResolverContext context,
        [Service] ProductsService productsService,
        CancellationToken cancellationToken,
        int id
    )
    {
        //Per the Annotation based Resolver signature here HC will inject the 'id' argument for us!
        //Otherwise this is just normal Resolver stuff...
        var productId = id;

        //Also you could get the argument from the IResolverContext...
        var productId = context.Argument<int>("id");. . . 
    }
public static class IResolverContextSortingExtensions
{
    /// <summary>
    /// Safely process the GraphQL context to retrieve the Order argument;
    /// matches the default name used by HotChocolate Sorting middleware (order: {{field1}: ASC, {field2}: DESC).
    /// Will return null if the order arguments/info is not available.
    /// </summary>
    /// <returns></returns>
    public static List<ISortOrderField>? GetSortingArgsSafely(this IResolverContext context, string sortOrderArgName = null!)
    {
        var results = new List<ISortOrderField>();

        //Unfortunately the Try/Catch is required to make this safe for easier coding when the argument is not specified,
        //  because the ResolverContext doesn't expose a method to check if an argument exists...
        try
        {
            var sortArgName = sortOrderArgName ?? SortConventionDefinition.DefaultArgumentName;

            //Get Sort Argument Fields and current Values...
            //NOTE: In order to correctly be able to Map names from GraphQL Schema to property/member names
            //      we need to get both the Fields (Schema) and the current order values...
            //NOTE: Not all Queries have Fields (e.g. no Selections, just a literal result), so .Field may
            //      throw internal NullReferenceException, hence we have the wrapper Try/Catch.
            IInputField sortArgField = context.Field.Arguments[sortArgName];
            ObjectValueNode sortArgValue = context.ArgumentLiteral<ObjectValueNode>(sortArgName);

            //Validate that we have some sort args specified and that the Type is correct (ListType of SortInputType values)...
            //NOTE: The Following processing logic was adapted from 'QueryableSortProvider' implementation in HotChocolate.Data core.
            //FIX: The types changed in v11.0.1/v11.0.2 the Sort Field types need to be checked with IsNull() method, and
            //      then against NonNullType.NamedType() is ISortInputType instead.
            if (!sortArgValue.IsNull()
                && sortArgField.Type is ListType lt
                && lt.ElementType is NonNullType nn 
                && nn.NamedType() is ISortInputType sortInputType)
            {
                //Create a Lookup for the Fields...
                var sortFieldLookup = sortInputType.Fields.OfType<SortField>().ToLookup(f => f.Name.ToString().ToLower());

                //Now only process the values provided, but initialize with the corresponding Field (metadata) for each value...
                var sortOrderFields = sortArgValue.Fields.Select(
                    f => new SortOrderField(
                        sortFieldLookup[f.Name.ToString().ToLower()].FirstOrDefault(), 
                        f.Value.ToString()
                    )
                );

                results.AddRange(sortOrderFields);
            }

            return results;
        }
        catch
        {
            //Always safely return at least an Empty List to help minimize Null Reference issues.
            return results;
        }
    }
}
-----------------------
public static class IResolverContextSelectionExtensions
{
    /// <summary>
    /// Similar to CollectFields in v10, this uses GetSelections but safely validates that the current context
    ///     has selections before returning them, it will safely return null if unable to do so.
    /// This is a variation of the helper method provided by HotChocolate team here: 
    ///     https://github.com/ChilliCream/hotchocolate/issues/1527#issuecomment-596175928
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static IReadOnlyList<PreProcessingSelection> GetPreProcessingSelections(this IResolverContext? context)
    {
        if (context == null)
            return null!;

        var selectionResults = new List<PreProcessingSelection>();

        var selections = GatherChildSelections(context!);
        if (selections.Any())
        {
            //BBernard
            //Determine if the Selection is for a Connection, and dive deeper to get the real
            //  selections from the node {} field.
            var lookup = selections.ToLookup(s => s.SelectionName.ToString().ToLower());

            //Handle paging cases; current Node is a Connection so we have to look for selections inside
            //  ->edges->nodes, or inside the ->nodes (shortcut per Relay spec); both of which may exist(?)
            if (lookup.Contains(SelectionNodeName.Nodes) || lookup.Contains(SelectionNodeName.Edges) || lookup.Contains(SelectionNodeName.Items))
            {
                //Cursor & Offset Paging are mutually exclusive so this small optimization prevents unnecessary processing...
                var searchOffsetPagingEnabled = true;

                //CURSOR PAGING SUPPORT - results are in either a 'Nodes' or 'Edges' Node!
                //NOTE: nodes and edges are not mutually exclusive per Relay spec so
                //          we gather from all if they are defined...
                if (lookup.Contains(SelectionNodeName.Nodes))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Nodes].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);

                    searchOffsetPagingEnabled = false;
                }

                if (lookup.Contains(SelectionNodeName.Edges))
                {
                    var edgesSelectionField = lookup[SelectionNodeName.Edges].FirstOrDefault();
                    //If Edges are specified then Selections are actually inside a nested 'Node' (singular, not plural) that we need to traverse...
                    var nodesSelectionField = FindChildSelectionByName(context, SelectionNodeName.EdgeNode, edgesSelectionField);
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                    
                    searchOffsetPagingEnabled = false;
                }

                //OFFSET PAGING SUPPORT - results are in an 'Items' Node!
                if (searchOffsetPagingEnabled && lookup.Contains(SelectionNodeName.Items))
                {
                    var nodesSelectionField = lookup[SelectionNodeName.Items].FirstOrDefault();
                    var childSelections = GatherChildSelections(context, nodesSelectionField);
                    selectionResults.AddRange(childSelections);
                }
            }
            //Handle Non-paging cases; current Node is an Entity...
            else
            {
                selectionResults.AddRange(selections);
            }
        }

        return selectionResults;
    }

    /// <summary>
    /// Find the selection that matches the specified name.
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <param name="selectionFieldName"></param>
    /// <returns></returns>
    private static PreProcessingSelection FindChildSelectionByName(IResolverContext? context, string selectionFieldName, PreProcessingSelection? baseSelection)
    {
        if (context == null)
            return null!;

        var childSelections = GatherChildSelections(context!, baseSelection);
        var resultSelection = childSelections?.FirstOrDefault(
            s => s.SelectionName.Equals(selectionFieldName, StringComparison.OrdinalIgnoreCase)
        )!;

        return resultSelection!;
    }

    /// <summary>
    /// Gather all child selections of the specified Selection
    /// For more info. on Node parsing logic see here:
    /// https://github.com/ChilliCream/hotchocolate/blob/a1f2438b74b19e965b560ca464a9a4a896dab79a/src/Core/Core.Tests/Execution/ResolverContextTests.cs#L83-L89
    /// </summary>
    /// <param name="context"></param>
    /// <param name="baseSelection"></param>
    /// <returns></returns>
    private static List<PreProcessingSelection> GatherChildSelections(IResolverContext? context, PreProcessingSelection? baseSelection = null)
    {
        if (context == null)
            return null!;

        var gathered = new List<PreProcessingSelection>();

        //Initialize the optional base field selection if specified...
        var baseFieldSelection = baseSelection?.GraphQLFieldSelection;
        
        //Dynamically support re-basing to the specified baseSelection or fallback to current Context.Field
        var field = baseFieldSelection?.Field ?? context.Field;

        //Initialize the optional SelectionSet to rebase processing as the root for GetSelections()
        //  if specified (but is optional & null safe)...
        SelectionSetNode? baseSelectionSetNode = baseFieldSelection is ISelection baseISelection
            ? baseISelection.SelectionSet
            : null!;

        //Get all possible ObjectType(s); InterfaceTypes & UnionTypes will have more than one...
        var objectTypes = GetObjectTypesSafely(field.Type, context.Schema);

        //Map all object types into PreProcessingSelection (adapter classes)...
        foreach (var objectType in objectTypes)
        {
            //Now we can process the ObjectType with the correct context (selectionSet may be null resulting
            //  in default behavior for current field.
            var childSelections = context.GetSelections(objectType, baseSelectionSetNode);
            var preprocessSelections = childSelections.Select(s => new PreProcessingSelection(objectType, s));
            gathered.AddRange(preprocessSelections);
        }

        return gathered;
    }

    /// <summary>
    /// ObjectType resolver function to get the current object type enhanced with support
    /// for InterfaceTypes & UnionTypes; initially modeled after from HotChocolate source:
    /// HotChocolate.Data -> SelectionVisitor`1.cs
    /// </summary>
    /// <param name="type"></param>
    /// <param name="objectType"></param>
    /// <param name="schema"></param>
    /// <returns></returns>
    private static List<ObjectType> GetObjectTypesSafely(IType type, ISchema schema)
    {
        var results = new List<ObjectType>();
        switch (type)
        {
            case NonNullType nonNullType:
                results.AddRange(GetObjectTypesSafely(nonNullType.NamedType(), schema));
                break;
            case ObjectType objType:
                results.Add(objType);
                break;
            case ListType listType:
                results.AddRange(GetObjectTypesSafely(listType.InnerType(), schema));
                break;
            case InterfaceType interfaceType:
                var possibleInterfaceTypes = schema.GetPossibleTypes(interfaceType);
                var objectTypesForInterface = possibleInterfaceTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForInterface);
                break;
            case UnionType unionType:
                var possibleUnionTypes = schema.GetPossibleTypes(unionType);
                var objectTypesForUnion = possibleUnionTypes.SelectMany(t => GetObjectTypesSafely(t, schema));
                results.AddRange(objectTypesForUnion);
                break;
        }

        return results;
    }
}
    [GraphQLName("products")]
    public async Task<IEnumerable<Products> GetProductsByIdAsync(
        IResolverContext context,
        [Service] ProductsService productsService,
        CancellationToken cancellationToken,
        int id
    )
    {
        //Per the Annotation based Resolver signature here HC will inject the 'id' argument for us!
        //Otherwise this is just normal Resolver stuff...
        var productId = id;

        //Also you could get the argument from the IResolverContext...
        var productId = context.Argument<int>("id");. . . 
    }
public static class IResolverContextSortingExtensions
{
    /// <summary>
    /// Safely process the GraphQL context to retrieve the Order argument;
    /// matches the default name used by HotChocolate Sorting middleware (order: {{field1}: ASC, {field2}: DESC).
    /// Will return null if the order arguments/info is not available.
    /// </summary>
    /// <returns></returns>
    public static List<ISortOrderField>? GetSortingArgsSafely(this IResolverContext context, string sortOrderArgName = null!)
    {
        var results = new List<ISortOrderField>();

        //Unfortunately the Try/Catch is required to make this safe for easier coding when the argument is not specified,
        //  because the ResolverContext doesn't expose a method to check if an argument exists...
        try
        {
            var sortArgName = sortOrderArgName ?? SortConventionDefinition.DefaultArgumentName;

            //Get Sort Argument Fields and current Values...
            //NOTE: In order to correctly be able to Map names from GraphQL Schema to property/member names
            //      we need to get both the Fields (Schema) and the current order values...
            //NOTE: Not all Queries have Fields (e.g. no Selections, just a literal result), so .Field may
            //      throw internal NullReferenceException, hence we have the wrapper Try/Catch.
            IInputField sortArgField = context.Field.Arguments[sortArgName];
            ObjectValueNode sortArgValue = context.ArgumentLiteral<ObjectValueNode>(sortArgName);

            //Validate that we have some sort args specified and that the Type is correct (ListType of SortInputType values)...
            //NOTE: The Following processing logic was adapted from 'QueryableSortProvider' implementation in HotChocolate.Data core.
            //FIX: The types changed in v11.0.1/v11.0.2 the Sort Field types need to be checked with IsNull() method, and
            //      then against NonNullType.NamedType() is ISortInputType instead.
            if (!sortArgValue.IsNull()
                && sortArgField.Type is ListType lt
                && lt.ElementType is NonNullType nn 
                && nn.NamedType() is ISortInputType sortInputType)
            {
                //Create a Lookup for the Fields...
                var sortFieldLookup = sortInputType.Fields.OfType<SortField>().ToLookup(f => f.Name.ToString().ToLower());

                //Now only process the values provided, but initialize with the corresponding Field (metadata) for each value...
                var sortOrderFields = sortArgValue.Fields.Select(
                    f => new SortOrderField(
                        sortFieldLookup[f.Name.ToString().ToLower()].FirstOrDefault(), 
                        f.Value.ToString()
                    )
                );

                results.AddRange(sortOrderFields);
            }

            return results;
        }
        catch
        {
            //Always safely return at least an Empty List to help minimize Null Reference issues.
            return results;
        }
    }
}

How to relate between entity and table with Dapper when it is not &quot;s&quot; difference

copy iconCopydownload iconDownload
using Dapper.Contrib.Extensions;

[Table("Taxes")]
public class Tax
{
    ...
}

Community Discussions

Trending Discussions on Dapper
  • Creating a specific dataset with LINQ
  • Why is an Azure Function on .NET 6 looking for System.ComponentModel Version 6.0.0.0?
  • How to setup .NET 6 with Dapper Identity and Discord Login
  • Is there some way with dapper object in object to load in sfdatagrid?
  • SqlClient connection pool maxed out when using async
  • Dapper Exception - &quot;The ConnectionString property has not been initialized&quot; when 'buffered' is 'false'
  • Why does a dapper query fail and a ado call not?
  • How do I add multiple &quot;WHERE conditionA OR conditionB OR conditionC&quot; in SQL parameter?
  • How to specify a Schema while mapping with DapperExtensions?
  • How to customize SQL query according to GraphQL request using HotChocolate and Dapper?
Trending Discussions on Dapper

QUESTION

Creating a specific dataset with LINQ

Asked 2022-Apr-08 at 13:50

I have trouble with creating one specific "dataset" from list of objects which I get via Dapper from database. So the thing is about daily attendancies in company, so user comes and click and goes out and click and we have one table row like this: sql table So I have a model class like this:

    public class Attendance
    {
        public int UserId { get; set; }
        public string FullName { get; set; }
        public DateTime DateTimeUtcIn { get; set; }
        public DateTime DateTimeUtcOut { get; set; }
        public string DayOfTheWeek { get; set; }
        public int LocationId { get; set; }
        public TimeSpan TotalTime { get; set; }
        public byte StatusId { get; set; }
        public TimeSpan BreakTime { get; set; }
    }

and then after a call to the database I have result like this IEnumerable<Attendace>:

var result = await _platformDB.Con.QueryAsync<Models.Attendance.Attendance>(query);

then I created a simple viewmodel like this:

    public class Time
    {
        public DateTime DateTimeUtcIn { get; set; }
        public DateTime DateTimeUtcOut { get; set; }
    }

    public class AttendaceViewModel
    {
        public int UserId { get; set; }
        public string FullName { get; set; }
        public string Date { get; set; }
        public string DayOfTheWeek { get; set; }
        public List<Time> TimesInAndOut { get; set; }
        public string Locations { get; set; }
        public string TotalTime { get; set; } //need to calculate
        public string Status { get; set; }
        public string BreakTime { get; set; } //need to calculate
     }

and here comes the QUESTION now: how can I create List<AttendaceViewModel> from my result grouped by UserId and calculate TotalTime for one day (sum of all dateTimeUtcIn + dateTimeUtcOut) and breaktime for this day and also populate this List<Time> TimesInAndOut in here? I have really no idea.

ANSWER

Answered 2022-Apr-08 at 12:31

You probably won't be able accomplish that with just LINQ. You should be able to loop over the items returned in the results that you just fetched, and do your logic there.

Implement a function like this, and call it after retrieving your results. You could even handle the database querying in this function too if you'd like, then just call the function and get back your list.

private List<AttendanceViewModel> GetAttendanceViewModels((whatever type 'results' is goes here) {type} results)
{
    var output = new List<AttendanceViewModel>();
    foreach(result in results)
    {
        var totalTime = CalculateTotalTimeForOneDay(result);
        var breakTime = CalculateBreakTime(result);
        result.TotalTime = totalTime;
        result.BreakTime = breakTime;
    }
    return output.GroupBy(u => u.UserId)
}

Source https://stackoverflow.com/questions/71796865

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install Dapper

You can download it from GitHub.

Support

For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Explore Related Topics

Share this Page

share link
Consider Popular SQL Database Libraries
Try Top Libraries by DapperLib
Compare SQL Database Libraries with Highest Support
Compare SQL Database Libraries with Highest Quality
Compare SQL Database Libraries with Highest Security
Compare SQL Database Libraries with Permissive License
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.