InvertedSoftware.DataBlock.Core
1.0.3
dotnet add package InvertedSoftware.DataBlock.Core --version 1.0.3
NuGet\Install-Package InvertedSoftware.DataBlock.Core -Version 1.0.3
<PackageReference Include="InvertedSoftware.DataBlock.Core" Version="1.0.3" />
paket add InvertedSoftware.DataBlock.Core --version 1.0.3
#r "nuget: InvertedSoftware.DataBlock.Core, 1.0.3"
// Install InvertedSoftware.DataBlock.Core as a Cake Addin #addin nuget:?package=InvertedSoftware.DataBlock.Core&version=1.0.3 // Install InvertedSoftware.DataBlock.Core as a Cake Tool #tool nuget:?package=InvertedSoftware.DataBlock.Core&version=1.0.3
The Inverted Software DateBlock has been recently enhanced, so I thought I would take the opportunity to write a short quick start tutorial that would help you get started with incorporating it into your application:
Getting objects
CRUDHelper.GetObject<Category>(() ⇒ new Category(), "GetCategory", mainConnectionString, new SqlParameter("@categoryCode", SqlDbType.VarChar, 200) { Value = "myValue" });
Getting collections
CRUDHelper.GetObjectList<Category>(() ⇒ new Category(), "GetCategories", mainConnectionString);
For a paged list use:
CRUDHelper.GetObjectList<Category>(() ⇒ new Category(), 0, 10, "GetCategories", mainConnectionString, out virtualTotal);
Getting parent child collections
If you use a single stored procedure to retrieve parent / child objects you have two methods of populating a list of parents and children: You can use an inner join query:
SELECT p.ProductID AS Product_ProductID, c.CategoryID AS Product_CategoryID, c.CategoryID AS Category_CategoryID, c.CategoryName AS Category_CategoryName, p.ProductName AS Product_ProductName
FROM Product p INNER JOIN ProductCategory pc ON p.ProductID = pc.ProductID INNER JOIN Category c WITH(NOLOCK) ON pc.CategoryID = c.CategoryID
with the following method:
CRUDHelper.GetEagerLoadedObjectListFromInnerJoinQuery<Category, Product>(() ⇒ new Category(), () ⇒ new Product(), "GetCategoriesWithProducts", mainConnectionString);
Or multiple result sets:
-- First select
SELECT CategoryID, CategoryName FROM Category WITH(NOLOCK)
-- second select
SELECT p.ProductID, c.CategoryID, p.ProductName
FROM Product p INNER JOIN ProductCategory pc ON p.ProductID = pc.ProductID INNER JOIN Category c WITH(NOLOCK) ON pc.CategoryID = c.CategoryID
with the following:
CRUDHelper.GetEagerLoadedObjectListFromMultipleResults<Category, Product>(() ⇒ new Category(), () ⇒ new Product(), "GetCategoriesWithProducts", mainConnectionString);
Getting collections of immutable objects
You can get a list of integers, strings or decimals.
CRUDHelper.GetIntList("GetCategoriesWithProducts", "CategoryID", mainConnectionString);
CRUDHelper.GetStringList("GetCategoriesWithProducts", "CategoryName", mainConnectionString);
Creating records from objects
CRUDHelper.AddObject<Category>(category, "AddCategory", mainConnectionString);
Updating objects
CRUDHelper.UpdateObject<Category>(category, "UpdateCutegory", mainConnectionString);
Deleting records
CRUDHelper.DeleteObject<Category>(category, "DeleteCategory", mainConnectionString);
Working with output parameters
public static List<T> GetObjectList<T>(Func<T> generator, int pageIndex, int rowsPerPage, string sprocName, string stringConnection, out int virtualTotal, params SqlParameter[] commandParameters) { List<T> objectList = new List<T>();
SqlParameter[] paramArray = new SqlParameter[]{
new SqlParameter("@PageIndex", SqlDbType.Int){ Value = pageIndex},
new SqlParameter("@PageSize", SqlDbType.Int){ Value = rowsPerPage},
new SqlParameter("@TotalRecords", SqlDbType.Int){ Direction = ParameterDirection.ReturnValue }
};
if (commandParameters != null)
paramArray = paramArray.Concat(commandParameters).ToArray();
SqlCommand cmd = SqlHelper.CommandPool.GetObject();
using (SqlConnection conn = new SqlConnection(stringConnection))
{
try
{
SqlHelper.PrepareCommand(cmd, conn, null, CommandType.StoredProcedure, sprocName, paramArray);
using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
PropertyInfo[] props = ObjectHelper.GetDataObjectInfo<T>().Properties;
List<string> columnList = ObjectHelper.GetColumnNames(rdr, sprocName);
T newobject;
while (rdr.Read())
{
newobject = generator();
ObjectHelper.LoadAs<T>(rdr, newobject, props, columnList, sprocName);
objectList.Add(newobject);
}
}
virtualTotal = Convert.ToInt32(paramArray.Where(p => p.ParameterName == "@TotalRecords").First().Value);
cmd.Parameters.Clear();
}
catch (Exception e)
{
throw new DataBlockException(String.Format("Error Getting object list {0}. Stored Procedure: {1}", typeof(T).FullName, sprocName), e);
}
finally
{
SqlHelper.CommandPool.PutObject(cmd);
}
}
return objectList;
}
Transactions
There are two ways of using transactions with the DataBlock:
SqlTransaction
public static int AddCategoryWithSqlTransaction() { int newRecordID = 0; using (SqlConnection connection = new SqlConnection(mainConnectionString)) { connection.Open(); SqlTransaction transaction = connection.BeginTransaction("SampleTransaction"); SqlParameter[] paramArray = new SqlParameter[]{ new SqlParameter("@ParentCategoryID", SqlDbType.Int){ Value = DBNull.Value}, new SqlParameter("@CategoryName", SqlDbType.VarChar, 50) { Value = "test1" }, new SqlParameter("@Active", SqlDbType.Bit) { Value = true } };
try
{
newRecordID = Convert.ToInt32(SqlHelper.ExecuteScalar(connection, transaction, CommandType.StoredProcedure, "AddCategory", paramArray));
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
return newRecordID;
}
And ScopeTransaction
public static int AddCategoryWithTransactionScope() { int newRecordID = 0; using (TransactionScope scope = new TransactionScope()) { SqlParameter[] paramArray = new SqlParameter[]{ new SqlParameter("@ParentCategoryID", SqlDbType.Int){ Value = DBNull.Value}, new SqlParameter("@CategoryName", SqlDbType.VarChar, 50) { Value = "test2" }, new SqlParameter("@Active", SqlDbType.Bit) { Value = true } };
try
{
newRecordID = Convert.ToInt32(SqlHelper.ExecuteScalar(mainConnectionString, CommandType.StoredProcedure, "AddCategory", paramArray));
scope.Complete();
}
catch (Exception ex)
{
throw ex;
}
}
return newRecordID;
}
Object attributes
The DataBlock uses property level attributes to perform mapping on CRUD operations as well as parent / child objects. Here is an example of typical attribute mapping:
public class Category { [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] [CrudField(UsedFor = CrudFieldType.Delete | CrudFieldType.Read | CrudFieldType.Update)] public int CategoryID { get; set; } public int? ParentCategoryID { get; set; } public string CategoryName { get; set; } [CrudField(UsedFor = CrudFieldType.DontUse)] public List<Product> CategoryProducts { get; set; } }
public class Product { [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] [CrudField(UsedFor = CrudFieldType.Delete | CrudFieldType.Read | CrudFieldType.Update)] public int ProductID { get; set; } public string ProductName { get; set; } [ForeignKey("CategoryID")] [CrudField(UsedFor = CrudFieldType.DontUse)] public int CategoryID { get; set; } }
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- Microsoft.Data.SqlClient (>= 5.2.1)
- Microsoft.Extensions.ObjectPool (>= 8.0.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Updated to .NET 8, Frozen Collections and object Pool