Author Archives: Ahmet AYDIN

Generate Custom SQL Operations On Dalyan Project

Introduction

Dalyan is a single page application project template using AngularJS, ASP.NET & Web API technologies. It is the base of a web application project. It has CRUD operation example with AngularJS. Additionally, WebAPI controllers and CRUD operations are created by T4 templates. You can download it from github source codes. This post describes step by step how to run this project and generate WebAPI CRUD Operations with T4 templates on Dalyan Project.

Generate Custom Database Operations

You can add CRUD operations with T4 template automaticly. Also you can add custom database operations to your project.

I will axplain the step by step how to add a new database operations.

The example is password change operation.

  1. Create ChangePassword Query and Query Handler
  2. Create ChangePassword Service
  3. Create ChangePassword WebAPI method

Create ChangePassword Query and Query Handler

Open Dalyan.Domain -> Query -> CustomQuery All db operations are in Dalyan.Domain project. Create a query class.

namespace Dalyan.Domain.Query
{
    using System;
    using Dalyan.Domain;
    using System.Linq;
    using System.Text;
    using Dalyan.Domain.Query;
    using System.Data;
    using System.Xml;
    using Dalyan.Db;
    using Entities.Models;
    using Dalyan.Entities.Enumerations;
    using AutoMapper;
    using System.Threading.Tasks;
    using System.Collections.Generic;

    public class ChangePasswordQuery : IQuery<bool>
    {
        public int Id { get; set; }
        public string Password { get; set; }
    }

    public class ChangePasswordQueryHandler : IQueryHandler<changepasswordquery, bool="">
    {
        private readonly DbEntities _db;
        public ChangePasswordQueryHandler()
        {
            _db = new DbEntities();
        }

        public bool Handler(ChangePasswordQuery query)
        {
            try
            {
                var obj = new Dalyan.Db.User();
                obj = _db.User.FirstOrDefault(x =&gt; x.Id == query.Id);
                obj.Password = query.Password;
                obj.UpdatedDate = DateTime.Now;
                _db.SaveChanges();
                return true;

            }
            catch (Exception ex)
            {
                throw new ExceptionLog(LogType.DATABASE_UPDATE, LogLevel.ERROR, ex, &quot;ChangePasswordQuery&quot;);
            }
        }
    }

}

ChangePasswordQuery class have your parameters and used in handler method. The parameter values pass with query class to handler.

Create ChangePassword Service

WebAPI use service layer to access database so you have to add a service class to Dalyan.Service solution.

namespace Dalyan.Service.Services
{
    using System;
    using SimpleInjector;
    using Dalyan.Domain;
    using System.Linq;
    using System.Text;
    using Dalyan.Domain.Query;
    using System.Data;
    using System.Xml;
    using Dalyan.Entities.Models;
    using Dalyan.Entities.Enumerations;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using Entities.Interfaces;
    using Entities.Contracts;

    public class ChangePasswordService
    {
        private readonly Container _container;
        public ChangePasswordService(Container container)
        {
            _container = container;
        }

        public ServiceResult<string> ChangePassword(int Id, string Password)
        {
            try
            {
                IMediator service = _container.GetInstance<imediator>();
                var query = new ChangePasswordQuery { Id = Id, Password=Password };
                return new ServiceResult<string>(service.Proccess(query).ToString(), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
            }
            catch (ExceptionLog ex)
            {
                LoggerService.Logger.Log(_container, ex);
                return new ServiceResult<string>(result: &quot;false&quot;, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
            }
        }
    }
}

We use mediator pattern and our handlers execute automaticly with mediator class with IoC.

Create ChangePassword WebAPI method

The last step is create WebAPI method. SPA project uses WebAPI methods to access database. You can add the method any controller.

    [ClientAuthorize]
    [HttpPost]
    public ServiceResult<string> ChangePassword(string password)
    {
        ChangePasswordService service = new ChangePasswordService(_container);
        IUserContext currentUser = _container.GetInstance<iusercontext>();
        return service.ChangePassword(currentUser.CurrentUserIdentity.UserID, password);
    }

Points of Interest

You can develop your project on Dalyan Web Application Template.

Generate Web API CRUD Operations Automatic With T4 Template on Dalyan Project

 Introduction

Dalyan is a single page application project template using AngularJS, ASP.NET & Web API technologies. It is the base of a web application project. It has CRUD operation example with AngularJS. Additionally, WebAPI controllers and CRUD operations are created by T4 templates. You can download it from github source codes.

This post describes step by step how to generate Web API CRUD Operations automatic With T4 Templates on Dalyan Project.

https://github.com/aydnahmet/Dalyan
You can create “Add, Edit, Delete, Retrieve and GetAll” actions after create you table on database.
Lets do it step by step!

  1. Create a “product” table on SQL Server Database
  2. Add “product” table to Dalyan.Db Entity Framework Edmx model
  3. Add “product” table to defination xml file
  4. Generate DbModel with T4 template
  5. Generate ServiceQuery with T4 template
  6. Generate Service with T4 template
  7. Generate WebAPI controller with T4 template
  8. Check WebAPI actions

1. Create a “product” table on SQL Server Database

You have to add these columns to your new table to create CRUD operations automatic.


[Id] [int] IDENTITY(1,1) NOT NULL, ----> For IDENTITY
[CreatedDate] [datetime] NULL, ----> For Logging Created Date automatic
[CreatedIpAddress] [nvarchar](50) NULL, ----> For Logging Created Ip Address automatic
[CreatedUserId] [int] NULL, ----> For Logging Created UserId automatic
[UpdatedDate] [datetime] NULL, ----> For Logging Updated Date automatic
[UpdatedIpAddress] [nvarchar](50) NULL, ----> For Logging Updated Ip Address automatic
[UpdatedUserId] [int] NULL, ----> For Logging Updated UserId automatic
[IsDeleted] [bit] NULL, ----> For Deleting operation automatic

Create a test table for testing t4 templates which name is “Product”

t4_1

You can add relationship to your columns.
I added CompanyId column relationship with Company table. On WebAPI response you can reach Company table with this relationship.

t4_2

Table Create Table Script


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Product](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CompanyId] [int] NULL,
[Name] [nvarchar](50) NULL,
[Description] [nvarchar](1000) NULL,
[Price] [float] NULL,
[CreatedDate] [datetime] NULL,
[CreatedIpAddress] [nvarchar](50) NULL,
[CreatedUserId] [int] NULL,
[UpdatedDate] [datetime] NULL,
[UpdatedIpAddress] [nvarchar](50) NULL,
[UpdatedUserId] [int] NULL,
[IsDeleted] [bit] NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_Company] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Company] ([Id])
GO

ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_Company]
GO

// Create Table Script

2. Add “product” table to Dalyan.Db Entity Framework Edmx model

Open Dalyan.Db project -> DalyanModel.edmx file.

t4_3
On DalyanModel.edmx file right click and Update Model From Database

t4_4

Add Product Table and save

t4_5

Now product table is added to edmx file.

3. Add “product” table to defination xml file

Code generation runs with edmx file but you have to add table name to defination.xml.

Open Dalyan.Entities -> Defination -> Tables.xml file

t4_6

And add this node to xml


&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;Tables&gt;
&lt;Table Name="Product"&gt;&lt;/Table&gt;
&lt;/Tables&gt;

4. Generate DbModel with T4 template

Models are generated by this T4 template.

Open Dalyan.Entities -> Models -> DbModel.tt file

And set you file location to absolutePath


public bool ControlTable(string tableName)
 {
 XmlDocument doc = new XmlDocument();
 string absolutePath = Path.GetFullPath(@"D:\Temp\Dalyan-master\Dalyan-master\Dalyan.Entities\Defination\Tables.xml");
 doc.Load(absolutePath);
 XmlNodeList xnList = doc.SelectNodes("/Tables/Table[@Name='" + tableName +"']");
 foreach (XmlNode xn in xnList)
 {
 return true;
 }
 return false;
 }

Run Custom Tool

t4_7

t4_8

Your model is ready

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from the Dalyan T4 template.
// Do not change
//
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Entities.Models
{
using System;
using System.Collections.Generic;

public partial class Product
{

public int Id { get; set; }

public Nullable<int> CompanyId { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public Nullable<double> Price { get; set; }

public Nullable<System.DateTime> CreatedDate { get; set; }

public string CreatedIpAddress { get; set; }

public Nullable<int> CreatedUserId { get; set; }

public Nullable<System.DateTime> UpdatedDate { get; set; }

public string UpdatedIpAddress { get; set; }

public Nullable<int> UpdatedUserId { get; set; }

public Nullable<bool> IsDeleted { get; set; }

public virtual Company Company { get; set; }

}

}

5. Generate ServiceQuery with T4 template

ServiceQuery is base layer to access database. It has CRUD operations and mapping operations in this layer.

Open Dalyan.Domain -> Query -> ServiceQuery.tt file

Right click and “Run Custom Tools”

t4_9

 

t4_10

ProductAddQuery

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Domain.Query
{

using System;
using Dalyan.Domain;
using System.Linq;
using System.Text;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Db;
using Entities.Models;
using Dalyan.Entities.Enumerations;
using AutoMapper;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductAddQuery : IQuery<Dalyan.Entities.Models.Product>
{
public Dalyan.Entities.Models.Product Product{ get; set; }
}

public class ProductAddQueryHandler : IQueryHandler<ProductAddQuery,Dalyan.Entities.Models.Product>
{
private readonly DbEntities _db;
public ProductAddQueryHandler()
{
_db = new DbEntities();
}

public Dalyan.Entities.Models.Product Handler(ProductAddQuery query)
{
try
{
var obj = new Dalyan.Db.Product();
obj.Id = query.Product.Id;
obj.CompanyId = query.Product.CompanyId;
obj.Name = query.Product.Name;
obj.Description = query.Product.Description;
obj.Price = query.Product.Price;
obj.CreatedDate = query.Product.CreatedDate;
obj.CreatedIpAddress = query.Product.CreatedIpAddress;
obj.CreatedUserId = query.Product.CreatedUserId;
obj.UpdatedDate = query.Product.UpdatedDate;
obj.UpdatedIpAddress = query.Product.UpdatedIpAddress;
obj.UpdatedUserId = query.Product.UpdatedUserId;
obj.IsDeleted = query.Product.IsDeleted;
_db.Product.Add(obj);
_db.SaveChanges();
query.Product.Id = obj.Id;
return query.Product;

}
catch (Exception ex)
{
throw new ExceptionLog(LogType.DATABASE_INSERT, LogLevel.ERROR, ex, "AddQueryHandler");
}
}
}

}

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Domain.Query
{

using System;
using Dalyan.Domain;
using System.Linq;
using System.Text;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Db;
using Entities.Models;
using Dalyan.Entities.Enumerations;
using AutoMapper;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductDeleteQuery : IQuery<bool>
{
public int Id { get; set; }
}

public class ProductDeleteQueryHandler : IQueryHandler<Dalyan.Domain.Query.ProductDeleteQuery, bool>
{
private readonly DbEntities _db;
public ProductDeleteQueryHandler()
{
_db = new DbEntities();
}

public bool Handler(Dalyan.Domain.Query.ProductDeleteQuery query)
{
try
{
var obj = new Dalyan.Db.Product();
obj = _db.Product.FirstOrDefault(x => x.Id == query.Id);

obj.IsDeleted = true;
_db.SaveChanges();
return true;
}
catch (Exception ex)
{
throw new ExceptionLog(LogType.DATABASE_DELETE, LogLevel.ERROR, ex, "DeleteQueryHandler");
}
}
}
}


//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Domain.Query
{

using System;
using Dalyan.Domain;
using System.Linq;
using System.Text;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Db;
using Entities.Models;
using Dalyan.Entities.Enumerations;
using AutoMapper;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductEditQuery : IQuery<Dalyan.Entities.Models.Product>
{
public Dalyan.Entities.Models.Product Product{ get; set; }
}

public class ProductEditQueryHandler : IQueryHandler<ProductEditQuery, Dalyan.Entities.Models.Product>
{
private readonly DbEntities _db;
public ProductEditQueryHandler()
{
_db = new DbEntities();
}

public Dalyan.Entities.Models.Product Handler(ProductEditQuery query)
{
try
{
var obj = new Dalyan.Db.Product();
obj = _db.Product.FirstOrDefault(x => x.Id == query.Product.Id);
obj.Id = query.Product.Id;
obj.CompanyId = query.Product.CompanyId;
obj.Name = query.Product.Name;
obj.Description = query.Product.Description;
obj.Price = query.Product.Price;
obj.CreatedDate = query.Product.CreatedDate;
obj.CreatedIpAddress = query.Product.CreatedIpAddress;
obj.CreatedUserId = query.Product.CreatedUserId;
obj.UpdatedDate = query.Product.UpdatedDate;
obj.UpdatedIpAddress = query.Product.UpdatedIpAddress;
obj.UpdatedUserId = query.Product.UpdatedUserId;
obj.IsDeleted = query.Product.IsDeleted;
_db.SaveChanges();
return query.Product;

}
catch (Exception ex)
{
throw new ExceptionLog(LogType.DATABASE_UPDATE, LogLevel.ERROR, ex, "EditQueryHandler");
}
}
}
}

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Domain.Query
{

using System;
using Dalyan.Domain;
using System.Linq;
using System.Text;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Db;
using Entities.Models;
using Dalyan.Entities.Enumerations;
using AutoMapper;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductGetAllQuery : IQuery<IList<Dalyan.Entities.Models.Product>>
{

}

public class ProductGetAllQueryHandler : IQueryHandler<ProductGetAllQuery, IList<Dalyan.Entities.Models.Product>>
{
private readonly DbEntities _db;
public ProductGetAllQueryHandler()
{
_db = new DbEntities();
}

public IList<Dalyan.Entities.Models.Product> Handler(ProductGetAllQuery query)
{
try
{
var result = _db.Product.Include("Company").Where(x => x.IsDeleted == false).AsEnumerable().ToList();
Mapper.CreateMap<Dalyan.Db.Company, Dalyan.Entities.Models.Company>();
Mapper.CreateMap<Dalyan.Db.Product, Dalyan.Entities.Models.Product>().ForMember(c => c.Company, d => d.MapFrom(s => s.Company));
return Mapper.Map<IEnumerable<Dalyan.Db.Product>, IEnumerable<Dalyan.Entities.Models.Product>>(result).ToList();

}
catch (Exception ex)
{
throw new ExceptionLog(LogType.DATABASE_SELECT, LogLevel.ERROR, ex, "GetAllQueryHandler");
}
}
}
}


---------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Domain.Query
{

using System;
using Dalyan.Domain;
using System.Linq;
using System.Text;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Db;
using Entities.Models;
using Dalyan.Entities.Enumerations;
using AutoMapper;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductRetrieveQuery : IQuery<Dalyan.Entities.Models.Product>
{
public int Id { get; set; }
}

public class ProductRetrieveQueryHandler : IQueryHandler<ProductRetrieveQuery, Dalyan.Entities.Models.Product>
{
private readonly DbEntities _db;
public ProductRetrieveQueryHandler()
{
_db = new DbEntities();
}

public Dalyan.Entities.Models.Product Handler(ProductRetrieveQuery query)
{
try
{
var result = _db.Product.Include("Company").Where(x => x.IsDeleted == false && x.Id == query.Id).FirstOrDefault();
Mapper.CreateMap<Dalyan.Db.Company, Dalyan.Entities.Models.Company>();
Mapper.CreateMap<Dalyan.Db.Product, Dalyan.Entities.Models.Product>().ForMember(c => c.Company, d => d.MapFrom(s => s.Company));
return Mapper.Map<Dalyan.Db.Product, Dalyan.Entities.Models.Product>(result);

}
catch (Exception ex)
{
throw new ExceptionLog(LogType.DATABASE_SELECT, LogLevel.ERROR, ex, "RetrieveQueryHandler");
}
}
}

}

6. Generate Service with T4 template

Service Layer is your business side. It calls the Domain layer to access database.

Open Dalyan.Service -> Services -> ServiceQueryHandler.tt file and “run custom tools”

t4_11
Your service code is ready.

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.Service.Services
{

using System;
using SimpleInjector;
using Dalyan.Domain;
using Entities.Contracts;
using System.Linq;
using System.Text;
using Dalyan.Entities.Interfaces;
using Dalyan.Domain.Query;
using System.Data;
using System.Xml;
using Dalyan.Entities.Models;
using Dalyan.Entities.Enumerations;
using System.Threading.Tasks;
using System.Collections.Generic;

public class ProductService
{
private readonly Container _container;
public ProductService(Container container)
{
_container = container;
}

public ServiceResult<Product> Add(Product obj)
{
try
{
IMediator service = _container.GetInstance<IMediator>();
IUserContext currentUser = _container.GetInstance<IUserContext>();
obj.CreatedDate = DateTime.Now;
obj.CreatedUserId = currentUser.CurrentUserIdentity.UserID;
obj.CreatedIpAddress = currentUser.CurrentUserIdentity.IpAddress;
obj.UpdatedDate = DateTime.Now;
obj.UpdatedUserId = currentUser.CurrentUserIdentity.UserID;
obj.UpdatedIpAddress = currentUser.CurrentUserIdentity.IpAddress;
obj.IsDeleted = false;
var query = new ProductAddQuery();
query.Product = obj;
return new ServiceResult<Product>(service.Proccess(query), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
}
catch(ExceptionLog ex)
{
LoggerService.Logger.Log(_container, ex);
return new ServiceResult<Product>(result: null, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
}
}
public ServiceResult<Product> Edit(Product obj)
{
try
{
IMediator service = _container.GetInstance<IMediator>();
IUserContext currentUser = _container.GetInstance<IUserContext>();
var query = new ProductEditQuery();
obj.UpdatedDate = DateTime.Now;
obj.UpdatedUserId = currentUser.CurrentUserIdentity.UserID;
obj.UpdatedIpAddress = currentUser.CurrentUserIdentity.IpAddress;
query.Product = obj;
return new ServiceResult<Product>(service.Proccess(query), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
}
catch(ExceptionLog ex)
{
LoggerService.Logger.Log(_container, ex);
return new ServiceResult<Product>(result: null, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
}
}
public ServiceResult<Product> Retrieve(int Id)
{
try
{
IMediator service = _container.GetInstance<IMediator>();
var query = new ProductRetrieveQuery{ Id = Id };
return new ServiceResult<Product>(service.Proccess(query), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
}
catch(ExceptionLog ex)
{
LoggerService.Logger.Log(_container, ex);
return new ServiceResult<Product>(result: null, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
}
}
public ServiceResult<IList<Product>> GetAll()
{
try
{
IMediator service = _container.GetInstance<IMediator>();
var query = new ProductGetAllQuery();
return new ServiceResult<IList<Product>>(service.Proccess(query), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
}
catch(ExceptionLog ex)
{
LoggerService.Logger.Log(_container, ex);
return new ServiceResult<IList<Product>>(result: null, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
}
}
public ServiceResult<string> Delete(int Id)
{
try
{
IMediator service = _container.GetInstance<IMediator>();
var query = new ProductDeleteQuery{ Id = Id };
return new ServiceResult<string>(service.Proccess(query).ToString(), message: ClientErrorMessage.Success(), state: ServiceResultStates.SUCCESS);
}
catch(ExceptionLog ex)
{
LoggerService.Logger.Log(_container, ex);
return new ServiceResult<string>(result: null, message: ClientErrorMessage.Error(), state: ServiceResultStates.ERROR);
}
}
}

}

7. Generate WebAPI controller with T4 template

The last one is WebAPI controller layer. Your SPA access this layer to CRUD operations.
For authentication add [UserAuthorize] Attributes to your action. [UserAuthorize] authentication is default.

Open Dalyan.WebApi project -> Controllers -> ControllerService.tt file

t4_12


//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalyan.WebApi.Controllers
{

using System;
using SimpleInjector;
using Dalyan.Entities;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Net.Http;
using Dalyan.Entities.Models;
using Dalyan.Service;
using Entities.Contracts;
using Dalyan.WebApi.Attributes;
using Dalyan.Service.Services;
using System.Collections.Generic;

public class ProductController : ApiController
{
private readonly Container _container;
public ProductController(Container container)
: base()
{
_container = container;
}

[UserAuthorize]
[HttpPost]
public ServiceResult<Product> Add(Product obj)
{
ProductService service = new ProductService(_container);
return service.Add(obj);
}
[UserAuthorize]
[HttpPost]
public ServiceResult<Product> Edit(Product obj)
{
ProductService service = new ProductService(_container);
return service.Edit(obj);
}
[UserAuthorize]
[HttpPost]
public ServiceResult<Product> Retrieve(int Id)
{
ProductService service = new ProductService(_container);
return service.Retrieve(Id);
}
[UserAuthorize]
[HttpPost]
public ServiceResult<IList<Product>> GetAll()
{
ProductService service = new ProductService(_container);
return service.GetAll();
}
[UserAuthorize]
[HttpPost]
public ServiceResult<string> Delete(int Id)
{
ProductService service = new ProductService(_container);
return service.Delete(Id);
}
}

}

8. Check WebAPI actions

For testing add some records to database


GO
SET IDENTITY_INSERT [dbo].[Company] ON

GO
INSERT [dbo].[Company] ([Id], [Name], [IsDeleted]) VALUES (1, N'Apple', 0)
GO
INSERT [dbo].[Company] ([Id], [Name], [IsDeleted]) VALUES (2, N'Samsung', 0)
GO
SET IDENTITY_INSERT [dbo].[Company] OFF
GO
SET IDENTITY_INSERT [dbo].[Product] ON
GO
INSERT [dbo].[Product] ([Id], [CompanyId], [Name], [Description], [Price], [CreatedDate], [CreatedIpAddress], [CreatedUserId], [UpdatedDate], [UpdatedIpAddress], [UpdatedUserId], [IsDeleted]) VALUES (1, 1, N'IPhone 6s', N'The only thing that’s changed is everything.', 350, CAST(N'2016-01-22 00:00:00.000' AS DateTime), N'192.1681.1', 1, CAST(N'2016-01-22 00:00:00.000' AS DateTime), N'192.1681.1', 1, 0)
GO
INSERT [dbo].[Product] ([Id], [CompanyId], [Name], [Description], [Price], [CreatedDate], [CreatedIpAddress], [CreatedUserId], [UpdatedDate], [UpdatedIpAddress], [UpdatedUserId], [IsDeleted]) VALUES (2, 2, N'Samsung Galaxy S6 edge', N'Big screen. Big entertainment.', 300, CAST(N'2016-01-22 00:00:00.000' AS DateTime), N'192.1681.1', 1, CAST(N'2016-01-22 00:00:00.000' AS DateTime), N'192.1681.1', 1, 0)
GO
SET IDENTITY_INSERT [dbo].[Product] OFF
GO

You can test you api from SPA code or postman chrome extension

https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop

The result of out call

http://localhost/Dalyan.WebApi/Product/GetAll

t4_13

{
"Result": [
{
"Id": 1,
"CompanyId": 1,
"Name": "IPhone 6s",
"Description": "The only thing that’s changed is everything.",
"Price": 350,
"CreatedDate": "2016-01-22T00:00:00",
"CreatedIpAddress": "192.1681.1",
"CreatedUserId": 1,
"UpdatedDate": "2016-01-22T00:00:00",
"UpdatedIpAddress": "192.1681.1",
"UpdatedUserId": 1,
"IsDeleted": false,
"Company": {
"Id": 1,
"Name": "Apple",
"IsDeleted": false
}
},
{
"Id": 2,
"CompanyId": 2,
"Name": "Samsung Galaxy S6 edge",
"Description": "Big screen. Big entertainment.",
"Price": 300,
"CreatedDate": "2016-01-22T00:00:00",
"CreatedIpAddress": "192.1681.1",
"CreatedUserId": 1,
"UpdatedDate": "2016-01-22T00:00:00",
"UpdatedIpAddress": "192.1681.1",
"UpdatedUserId": 1,
"IsDeleted": false,
"Company": {
"Id": 2,
"Name": "Samsung",
"IsDeleted": false
}
}
],
"ResultList": null,
"State": 0,
"Message": "Your transaction has been completed successfully.",
"PortalTask": null
}

-- Thank you
-- Ahmet AYDIN

Run Single Page Applications (SPA) Template using AngularJS, Web API, Owin Token Based Authentication and Mediator Design Pattern

This post describes step by step how to run a Single Page Application template using ASP.NET Web API 2 and angularJS and how to use Web Application Project whose name is Dalyan.

 

Introduction

Dalyan is a single page application project template using AngularJS, ASP.NET & Web API technologies. It is the base of a web application project. It has CRUD operation example with AngularJS. Additionally, WebAPI controllers and CRUD operations are created by T4 templates. You can download it from github source codes. This post describes step by step how to run this project.

 

github

https://github.com/aydnahmet/Dalyan/

asp

What Are We Going to Build

ss1

ss2

 

Framework – Tools – Libraries

  • Single Page Application
  • AngularJS
  • ASP.NET MVC 5
  • ASP.NET Web API 2
  • Entity Framework 6
  • Mediator Design Pattern
  • Owin Token Based Authentication
  • Bootstrap 3
  • Simple Injector Dependency Injection (DI)
  • 3rd part libraries
  • T4 Templates
  • Microsoft Sql Server Express

Project Architecture

arc

Configure Application

Open the Dalyan solution (Dalyan.sln) which is located in root directory and build the solution.

Publish Database Project

Database project has base tables and some data to test project.

cp1

Open database project and click publish button.

cp2

Set your database connection string and create your database.

cp3

Set Connection Strings

Change Db project and Web API config files.

Dalyan.WebApi\Web.Config and Dalyan.Db\App.Config

    .\SQLEXPRESS;
    initial catalog=Dalyan.Github;integrated security=True;
    MultipleActiveResultSets=True;App=EntityFramework"" 
    providerName="System.Data.EntityClient" />

Ready to Run

It is ready to run. You can open the project in this link.

Also web API link:

Default authentication:

cp5

Points of Interest

You can develop your project on Dalyan Web Application Template.

DNX SDK Version ‘dnx-clr-win-x86.1.0.0-beta5′ Failed to Install & References Cannot Load

asp.net

DNX SDK version 'dnx-clr-win-x86.1.0.0-beta5' failed to install. 
The solution will use DNX SDK version dnx-clr-win-x86.1.0.0-beta5

You receive this error when you create a new ASP.NET 5 project template. Loading project Visual Studio cannot load DNX version beta5.

Install Windows Powershell 3.0 (or higher) and try to create the project again.
http://www.microsoft.com/en-us/download/details.aspx?id=40855

You can see Powershell version with this $PSVersionTable command.

After installed Powershell, the ASP.NET 5 project can open.

DNX 4.5.1 & DNX Core 5 References Cannot Load

ASP.NET 5 project template needs the dnx-beta version so it cannot load references. You have to check which dnx verison loaded and which one is default.

 

To check DNX installed and default version with this command:

dnvm list

 

 

beta5 clr version installed but it is not default. Need to install beta5 coreclr version.

To install beta5 coreclr verison, use this command:

dnvm install -r coreclr 1.0.0-beta5

After install beta5 coreclr version, check again versions:

Now beta5 coreclr and clr versions are installed, so we can set our project “DNX SDK Version” because when you create a new project SDK version, set default DNX version. Our default DNX version is beta7. We have to change it to fix reference problem.

You can change it from solution properties.

Points of Interest

DNX problem can be solved step by step. Smile | :) You have to check versions and default values.

RANK ve DENSE_RANK Fonksiyonları

sqlserver

Rank ve Danse_Rank fonksiyonları ROW_NUMBER fonksiyonu gibi gruplama işlemleri yapmaktadır.

RANK fonksiyonun ROW_NUMBER fonksiyonundan farkı gruplama işleminde sıralama yapıldığında RANK sıralamada aynı değere sahip olan değerlere aynı RANK değerini atar. ROW_NUMBER da ise sıralamada aynı olması durumda bile değer artarak devam eder. Aynı tablo üzerinde üç fonksiyonunda yazıp farklarını görelim.

Select i.ProductID,i.LocationID,i.Quantity,
ROW_NUMBER() OVER(PARTITION BY i.LocationId
ORDER BY i.Quantity DESC) As RowNumber
From Production.ProductInventory
i inner join
Production.Product p on
i.ProductID = p.ProductID
where i.ProductID in (436,461,443)

Select i.ProductID,i.LocationID,i.Quantity,
DENSE_RANK() OVER(PARTITION BY i.LocationId
ORDER BY i.Quantity DESC) As 'DENSE_RANK'
From Production.ProductInventory i
inner join
Production.Product p
on i.ProductID = p.ProductID
where i.ProductID in (436,461,443)

Select i.ProductID,i.LocationID,i.Quantity,
RANK() OVER(PARTITION BY i.LocationId
ORDER BY i.Quantity DESC) As RANK
From Production.ProductInventory i
inner join
Production.Product p
on i.ProductID = p.ProductID
where i.ProductID in (436,461,443)
RANK
ProductID LocationID Quantity RANK
436 1 627 1
461 1 627 1
443 1 625 3
436 6 521 1
461 6 521 1
443 6 520 3
436 50 504 1
461 50 504 1
443 50 502 3
DENSE RANK
ProductID LocationID Quantity DENSE_RANK
436 1 627 1
461 1 627 1
443 1 625 2
436 6 521 1
461 6 521 1
443 6 520 2
436 50 504 1
461 50 504 1
443 50 502 2
ROW_NUMBER
ProductID LocationID Quantity ROW_NUMBER
436 1 627 1
461 1 627 2
443 1 625 3
436 6 521 1
461 6 521 2
443 6 520 3
436 50 504 1
461 50 504 2
443 50 502 3
Category: SQL

ROW_NUMBER Fonksiyonu

Veri kümesinde gruplanmış her değer için numerik ve artan bir değer üretir. ROW_NUMBER ile yapacağınız gruplamaya göre numerik sayı ürettirip bunlar arasında top değer ya da kriter ayrımı ile daha karmaşık sorguları daha basit bir şekilde yazabilirsiniz.

Select FirstName,LastName,
ROW_NUMBER() OVER(ORDER BY SalesYTD DESC)
As RowNumber,
SalesYTD,JobTitle
From Sales.vSalesPerson

Yukarı kod ile SalesYTD kolunda en yüksek değerden en düşüğe doğru bir sıralama yaparak row number numerik artan değer vermektedir.

FirstName LastName RowNumber SalesYTD JobTitle
Linda Mitchell 1 4251368,55 Sales Representative
Jae Pak 2 4116871,228 Sales Representative
Michael Blythe 3 3763178,179 Sales Representative
Jillian Carson 4 3189418,366 Sales Representative
Ranjit Varkey Chudukatil 5 3121616,32 Sales Representative
José Saraiva 6 2604540,717 Sales Representative
Shu Ito 7 2458535,617 Sales Representative
Tsvi Reiter 8 2315185,611 Sales Representative
Rachel Valdez 9 1827066,712 Sales Representative
Tete Mensa-Annan 10 1576562,197 Sales Representative
David Campbell 11 1573012,938 Sales Representative
Garrett Vargas 12 1453719,465 Sales Representative
Lynn Tsoflias 13 1421810,924 Sales Representative
Pamela Ansman-Wolfe 14 1352577,133 Sales Representative
Stephen Jiang 15 559697,5639 North American Sales Manager
Amy Alberts 16 519905,932 European Sales Manager
Syed Abbas 17 172524,4512 Pacific Sales Manager

Aşağıdaki kod örneğinde ise ROW_NUMBER fonksiyonuna PARTITION BY eklemesi yaparak JobTitle a göre en yüksek SalesYTD alanı ile sıralama yapacağız.

Select FirstName,LastName,
ROW_NUMBER()
OVER(PARTITION BY JobTitle ORDER BY SalesYTD DESC)
As RowNumber,
SalesYTD,JobTitle
From Sales.vSalesPerson
FirstName LastName RowNumber SalesYTD JobTitle
Amy Alberts 1 519905,932 European Sales Manager
Stephen Jiang 1 559697,5639 North American Sales Manager
Syed Abbas 1 172524,4512 Pacific Sales Manager
Linda Mitchell 1 4251368,55 Sales Representative
Jae Pak 2 4116871,228 Sales Representative
Michael Blythe 3 3763178,179 Sales Representative
Jillian Carson 4 3189418,366 Sales Representative
Ranjit Varkey Chudukatil 5 3121616,32 Sales Representative
José Saraiva 6 2604540,717 Sales Representative
Shu Ito 7 2458535,617 Sales Representative
Tsvi Reiter 8 2315185,611 Sales Representative
Rachel Valdez 9 1827066,712 Sales Representative
Tete Mensa-Annan 10 1576562,197 Sales Representative
David Campbell 11 1573012,938 Sales Representative
Garrett Vargas 12 1453719,465 Sales Representative
Lynn Tsoflias 13 1421810,924 Sales Representative
Pamela Ansman-Wolfe 14 1352577,133 Sales Representative

JobTitle göre gruplama yaptığımız için her yeni Jobtitle veri kümesi 1 den başlamıştır. Buradaki sıralama satış oranlarının yüksekten düşüğe göre olduğundan Row Number alanı 1 olanları sorgu üzerinden çekmemiz sadece en yüksek satışı yapan personelin listesini verecektir.

Category: SQL

Group By Cube ve Group By Rollup Operatörleri

Group By Cube

Tüm verilerin gruplanmasına ilave olarak verilerin toplamlarını göstermenizi sağlamaktadır.

select isnull(Cast(ProductID as nvarchar(50)),'Toplam') as ProducId,
sum(StandardCost) as Total from [Production].[ProductCostHistory]
where ProductID in (707,708)
Group by cube (ProductID)
ProducId Total
707 38,9923
708 38,9923
Toplam 77,9846

Group By Rollup

Gruplama yaptığımız veri üzerinde hem ara toplam hemde genel toplam almamızı sağlayan operatördür.

Select isnull(i.Shelf, 'Genel') as Shelf,
isnull(p.Name,isnull(i.Shelf, 'Genel') + ' Toplam') as Name,
Sum(i.Quantity) as Total
From Production.ProductInventory i
inner join Production.Product p
On i.ProductID = p.ProductID
Where p.name like 'B%'
group by rollup (i.Shelf, p.Name)
Shelf Name Total
A BB Ball Bearing 909
A Bearing Ball 791
A Blade 532
A A Toplam 2232
B BB Ball Bearing 443
B Bearing Ball 318
B Blade 829
B B Toplam 1590
N/A Bike Wash – Dissolver 36
N/A N/A Toplam 36
Genel Genel Toplam 3858
Category: SQL

Except ve Intersect Komutları

Except komutu iki data setimizde ilk datasetinde olup ikinci datasetinde olmayan yeni bir dataset verir bize.

Örnek olarak A tablosunda 1,2,3 kayıtları olsun. B tablosunda ise 3,4 kayıtları olsun. Aşağıdaki gibi kodumuzu yazdığımızda yeni oluşacak dataset üzerinde sadece 1,2 kayıtları olacaktır.

Select Id From A
Except
Select Id From B

Except komutundan alacağınız sonucu Not in operatörü ile de alabilirsiniz.

Select Id From A Where Id Not In (Select Id From B)

Intersect komutu ise iki tablo arasındaki kesişim değerlerini almaktadır. A ve B tablosu için düşünürsek geri dönen kayıt sadece 3 değeri olacaktır.

Select Id From A
Intersect
Select Id From B
Category: SQL

Having Operatörü

Group by ifadesi ile gruplama yaptığımız kolonlar üzerinden kriter belirtmemizi sağlayan operatördür. Kullanımı aşağıdaki gibidir.

select ProductID,COUNT(ProductID)
from [Sales].[SalesOrderDetail]
GROUP BY ProductID
HAVING COUNT(ProductID) &gt; 500

SalesOrderDetail tablosunda yer alan ürün sayısı 500 den fazla olan kayıtların listelenmesini sağlar

Category: SQL

Count Fonksiyonu

SQL sorgularında en çok kullanılan fonksiyonlardan bir tanesidir. Tabloda Null olmayan satırların toplamını verir.

Select Count(*) From Person.Person

Tabloda bulunan kayıt sayısını verir.

Select Count(Title) From Person.Person

Title kolonunda Null olmayan kayıtların sayısını verir.

Select Count(Distinct Title) From Person.Person

Title kolonunda Null olmayan ve birbirinden farklı olan kayıt sayısını verir.

Category: SQL