SSDT Installation

Recent changes in Visual studio installer is breaking SSDT installation with this error;

We need to do an offline installation as outlined here;

https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt?view=sql-server-2017#ssdt-for-vs-2017-standalone-installer&WT.mc_id=DP-MVP-5003166

Download SSDT from here;

https://go.microsoft.com/fwlink/?linkid=2169967&WT.mc_id=DP-MVP-5003166

Download vs_sql.exe file from here;

https://aka.ms/vs/15/release/vs_sql.exe

Open DOS prompt as administrator and navigate to downloaded files
MS DOS
vs_sql.exe –layout C:\Business\Trash\SSDT\OfflineFiles –lang en-us

If there is error in download, type the command below to fix the error: (only do this if you also had download errors) ;

vs_SQL.exe –layout C:\SSDT2017 –fix

Navigate to the directory where you downloaded the layout files (in my case, C:\Business\Trash\SSDT\OfflineFiles)
vs_setup.exe –NoWeb

There’s not much to change here, just click on the Install button (or maybe change the installation path):

Once installation is done, we will be able to see a minimal version of VS2017.
Now we can install SQL Server Data Tools 2017 (SSDT) ​​through the normal installer (SSDT-Setup-ENU.exe), remembering to check the SSIS, SSRS and SSAS options:
SSDT-Setup-ENU

Once the installatin is successful, make sure the SQL Server project templates (Database Project / SQLCLR), Analysis Services (SSAS), Integration Services (SSIS) and Reporting Services (SSRS) are working normally.

You are done.

Update for VS2022

Microsoft added a public preview of the SQL Server Integration Services Projects 2022 to the Visual Studio marketplace, which is tested against Visual Studio 2022 17.4

You can read full discussion on stack overflow.

Reference

https://en.dirceuresende.com/blog/como-corrigir-erro-na-instalacao-do-sql-server-data-tools-ssdt-2017-setup-failed-incorrect-function-0x80070001/

Pass parameters to action method in ASP.NET Core

One of the simplest and easiest ways to pass parameters to an action method is passing it via the URL. The following code snippet illustrates how you can pass parameters in the URL.

[HttpGet]
[Route("Default/GetAuthor/{authorId:int}")]
public IActionResult GetAuthor(int authorId)
{
   var data = authorRepository.GetAuthor(authorId);
   return View(data);
}

The URL to the endpoint is:

GET: http://localhost:8061/Default/GetAuthor/1

Here are some of links;

https://www.infoworld.com/article/3568209/how-to-pass-parameters-to-action-methods-in-asp-net-core-mvc.html

Executing Raw SQL Queries using EF Core

Here are some methods;

DbSet.FromSqlRaw

The DbSet.FromSqlRaw method (DbSet.FromSql prior to Entity Framework Core 3.0) enables you to pass in a SQL command to be executed against the database to return instances of the type represented by the DbSet:

public class Book
{
    public int BookId { get; set; }
    public string Title { get; set; }
    public Author Author { get; set; }
    public int AuthorId{ get; set; }
    public string Isbn { get; set; }
}
...
public class SampleContext : DbContext
{
    public DbSet<Book> Books { get; set; }
}
using (var context = new SampleContext())
{
    var books = context.Books.FromSqlRaw("SELECT BookId, Title, AuthorId, Isbn FROM Books").ToList();
}

The DbSet must be included in the model (i.e. it can not be configured as Ignored). All columns in the target table that map to properties on the entity must be included in the SQL statement. The column names must match those that the properties are mapped to. Property names are not taken into account when the results are hydrated into instances of the entity.

If any columns are missing, or are returned with names not mapped to properties, an InvalidOperationException will be raised .

Parameterized Queries

It’s always advised to parameterize user input to prevent the possibility of a SQL injection attack being successful. Entity Framework Core will parameterize SQL if you use format strings with FromSqlRaw or string interpolation with the FromSqlInterpolated method:

// Format string
var author = db.Authors.FromSqlRaw("SELECT * From Authors Where AuthorId = {0}", id).FirstOrDefault();
// String interpolation
var author = db.Authors.FromSqlInterpolated($"SELECT * From Authors Where AuthorId = {id}").FirstOrDefault();

Both of these approaches result in the following SQL being generated;

SELECT "a"."AuthorId", "a"."FirstName", "a"."LastName"
FROM (
    SELECT * From Authors Where AuthorId = @p0
) AS "a"
LIMIT 1

Entity Framework Core will only parameterize format strings if they are supplied inline to the FromSqlRaw method call. Format strings declared outside of the FromSqlRaw method call will not be parsed for parameter placeholders. In effect, you will be passing a concatenated string directly to the database, which is a SQL injection risk.

The following example is dangerous and should not be used:

var sql = string.Format("SELECT * From Authors Where AuthorId = {0}", id);
var author = db.Authors.FromSqlRaw(sql).FirstOrDefault(); 

The generated SQL is unparameterized:

SELECT "a"."AuthorId", "a"."FirstName", "a"."LastName"
FROM (
  SELECT * From Authors Where AuthorId = 2
) AS "a"
LIMIT 1

Stored Procedures

The SQL command can be any valid SQL statement that returns all the required fields of data. It is possible to call stored procedures via the FromSqlRaw method:

using (var context = new SampleContext())
{
    var books = context.Books
        .FromSqlRaw("EXEC GetAllBooks")
        .ToList();
}

It is also possible to pass in values to named parameters:

using (var context = new SampleContext())
{
    var authorId = new SqlParameter("@AuthorId", 1);
    var books = context.Books
        .FromSqlRaw("EXEC GetBooksByAuthor @AuthorId" , authorId)
        .ToList();
}

Non-Entity Types and Projections

In versions of EF Core prior to 2.1, it is not possible to use the FromSqlRaw method to return a subset of properties (a projection) directly from the database. Using the Books DbSet above as an example, the following will not work:

using(var context = new SampleContext())
{
    var books = context.Books.FromSqlRaw("SELECT BookId, Title FROM Books").ToList();
}

You must project the result of the FromSqlRaw method call to return a subset of properties:

using(var context = new SampleContext())
{
    var books = context.Books
        .FromSql("SELECT * FROM Books")
        .Select(b => new {
            BookId = b.BookId,
            Title = b.Title 
            }).ToList();
}

However, this may prove inefficient as all columns from the mapped table will be returned by the FromSql method call.

Support for returning ad hoc (not DbSet) types from direct SQL calls is possible from EF Core 2.1.

Database.ExecuteSqlCommand

The DbContext exposes a Database property which includes a method called ExecuteSqlCommand. This method returns an integer specifying the number of rows affected by the SQL statement passed to it. Valid operations are INSERTUPDATE and DELETE. The method is not used for returning entities.

using(var context = new SampleContext())
{
    var commandText = "INSERT Categories (CategoryName) VALUES (@CategoryName)";
    var name = new SqlParameter("@CategoryName", "Test");
    context.Database.ExecuteSqlCommand(commandText, name);
}

Note: You will need to add using Microsoft.Data.SqlClient; to make the SqlParameter type available to your code.

The ExecuteSqlCommand method can also be used to execute stored procedures:

using(var context = new SampleContext())
{
    var name = new SqlParameter("@CategoryName", "Test");
    context.Database.ExecuteSqlCommand("EXEC AddCategory @CategoryName", name);
}

Leveraging ADO.NET via the Context.Database property

In addition to the ExecuteSqlCommand method, the DbContext.Database property provides an API that allows you to perform ADO.NET operations directly. The GetDbConnection method returns a DbConnection object representing the context’s underlying connection. From that point, you can revert to the familiar ADO.NET APIs:

using (var context = new SampleContext())
using (var command = context.Database.GetDbConnection().CreateCommand())
{
    command.CommandText = "SELECT * From Table1";
    context.Database.OpenConnection();
    using (var result = command.ExecuteReader())
    {
        // do something with result
    }
}

EF CORE..

Stop tracking the files that should be ignored in Git

To stop tracking the files in the ignore file open a command prompt or terminal window from your Visual Studio and navigate to the directory that contains your solution file (.sln) and run the following commands.

git rm -r --cached . 
git add .
git commit -am "Remove ignored files"

That seemed to do the trick for me. The git commands I found here. If you click on that link you will see there are lots of options on which commands to use for this process. If the above doesn’t work for you one of the other answers should meet your needs.

How to add gitignore file existing solution using Visual Studio

Standard Practice to Create Repository

Using fieldset legend with bootstrap

Fieldsets are a set or collection of input fields in a form, used on a web page to collect user data. Legends are simply titles (also known as “captions”) that are added to the fieldsets to distinguish them from each other, thus improving UX.

“Fieldsets + Legends” are usually styled with a border that wraps the fieldset elements inside it, and the legend as a title on top of it.

<fieldset class="scheduler-border">
    <legend class="scheduler-border">Start Time</legend>
    <div class="control-group">
        <label class="control-label input-label" for="startTime">Start :</label>
        <div class="controls bootstrap-timepicker">
            <input type="text" class="datetime" id="startTime" name="startTime" placeholder="Start Time" />
            <i class="icon-time"></i>
        </div>
    </div>
</fieldset>

CSS is

fieldset.scheduler-border {
    border: 1px groove #ddd !important;
    padding: 0 1.4em 1.4em 1.4em !important;
    margin: 0 0 1.5em 0 !important;
    -webkit-box-shadow:  0px 0px 0px 0px #000;
            box-shadow:  0px 0px 0px 0px #000;
}

legend.scheduler-border {
   width: inherit; /* Or auto */
   padding: 0 10px; /* To give a bit of padding on the left and right */
   border-bottom: none;
   font-size: 16px;
}

This would be the output;

Reference

https://stackoverflow.com/questions/16852484/use-fieldset-legend-with-bootstrap

https://azmind.com/bootstrap-fieldset-legend/