Skip to content

Instantly share code, notes, and snippets.

@mikedll
Last active October 30, 2018 00:14
Show Gist options
  • Save mikedll/0c709b15671339a81f2c595c2479a675 to your computer and use it in GitHub Desktop.
Save mikedll/0c709b15671339a81f2c595c2479a675 to your computer and use it in GitHub Desktop.
SQL Server Schemas and non-EF way of working with db data.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace DScrib2.Models
{
public class User
{
public int ID;
public string Email;
public string VendorID;
}
public class Review
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public string Text { get; set; }
public string Slug { get; set; }
public string AmazonID { get; set; }
public int UserID { get; set; }
}
public class DbWrapper
{
private string connectionString = "Data Source=(local);Initial Catalog=DScrib2;Integrated Security=true";
/*
* Ignores ID field of reference if set.
*
* Assumes sql is remainder of INSERT INTO statement.
*
* Return ID resulting from INSERT statement.
*/
private int SaveOne(string sql, Action<SqlCommand> paramsAdder)
{
int newID = -1;
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand("INSERT INTO " + sql, connection);
paramsAdder(command);
try
{
connection.Open();
newID = (int)command.ExecuteScalar();
}
catch (Exception ex)
{
if (ex.Message.StartsWith("Violation of UNIQUE KEY constraint"))
{
throw new Exception("Insertion would have violated unique key constraint.");
// propogate error?
}
else
{
// Log error?
throw;
}
}
}
return newID;
}
private T GetOne<T>(string sql, Action<SqlCommand> paramsAdder, Func<SqlDataReader, T> builder)
{
T found = default(T);
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(sql, connection);
paramsAdder(command);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read()) found = builder(reader);
}
catch (Exception)
{
// Log error?
throw;
}
}
return found;
}
private List<T> GetMany<T>(string sql, Action<SqlCommand> paramsAdder, Func<SqlDataReader, T> builder)
{
List<T> returning = new List<T>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(sql, connection);
paramsAdder(command);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while(reader.Read()) returning.Add(builder(reader));
}
catch (Exception)
{
// Log error?
throw;
}
}
return returning;
}
public User CreateUser(User user)
{
var newID = SaveOne("\"User\" (Email, VendorID) OUTPUT INSERTED.ID VALUES (@email, @vendorID)", (cmd) =>
{
cmd.Parameters.AddWithValue("@email", user.Email);
cmd.Parameters.AddWithValue("@vendorID", user.VendorID);
});
user.ID = newID;
return user;
}
public Review SaveReview(Review review)
{
var newID = SaveOne("Review (Name, Text, Date, Slug, AmazonID, UserID) OUTPUT INSERTED.ID VALUES (@name, @text, @date, @slug, @amazonID, @userID)", (cmd) =>
{
cmd.Parameters.AddWithValue("@name", review.Name);
cmd.Parameters.AddWithValue("@text", review.Text);
cmd.Parameters.AddWithValue("@date", review.Date);
cmd.Parameters.AddWithValue("@slug", review.Slug);
cmd.Parameters.AddWithValue("@amazonID", review.AmazonID);
cmd.Parameters.AddWithValue("@userID", review.UserID);
});
review.ID = newID;
return review;
}
public Review GetReview(string linkSlug, string productID)
{
return GetOne("SELECT ID, Name, Text, Date, Slug, AmazonID, UserID FROM Review WHERE Slug = @slug AND AmazonID = @amazonID", (cmd) =>
{
cmd.Parameters.AddWithValue("@slug", linkSlug);
cmd.Parameters.AddWithValue("@amazonID", productID);
}, (reader) =>
{
return new Review
{
ID = reader.GetInt32(0),
Name = reader.GetString(1),
Text = reader.GetString(2),
Date = reader.GetDateTime(3),
Slug = reader.GetString(4),
AmazonID = reader.GetString(5),
UserID = reader.GetInt32(6)
};
});
}
public List<Review> GetReviewsForUser(User user)
{
return GetMany("SELECT ID, Name, Text, Date, Slug, AmazonID, UserID FROM Review WHERE UserID = @userID", (cmd) =>
{
cmd.Parameters.AddWithValue("@userID", user.ID);
}, (reader) =>
{
return new Review
{
ID = reader.GetInt32(0),
Name = reader.GetString(1),
Text = reader.GetString(2),
Date = reader.GetDateTime(3),
Slug = reader.GetString(4),
AmazonID = reader.GetString(5),
UserID = reader.GetInt32(6)
};
});
}
public User GetUser(int ID)
{
return GetOne("SELECT ID, Email, VendorID FROM \"User\" WHERE ID = @id", (cmd) => cmd.Parameters.AddWithValue("@id", ID), (reader) => {
return new User()
{
ID = reader.GetInt32(0),
Email = reader.GetString(1),
VendorID = reader.GetString(2)
};
});
}
/*
* Returns null if user canot be found. Returns User otherwise.
*/
public User GetUserByVendorID(string subject)
{
return GetOne("SELECT ID, Email, VendorID FROM \"User\" WHERE VendorID = @vid", (cmd) => cmd.Parameters.AddWithValue("@vid", subject), (reader) =>
{
return new User()
{
ID = reader.GetInt32(0),
Email = reader.GetString(1),
VendorID = reader.GetString(2)
};
});
}
}
}
-- Test it out
INSERT INTO "User" (Email, VendorID) VALUES ('sam@example.com', '12345');
INSERT INTO "User" (Email, VendorID) VALUES ('sam@example.com', '123456');
-- See insertions.
SELECT ID, Email, VendorID FROM "User"
-- Schema.
DROP TABLE Review
DROP TABLE "User"
CREATE TABLE "User" (
"ID" INT IDENTITY PRIMARY KEY,
"Email" NVARCHAR(200) NOT NULL,
"VendorID" NVARCHAR(50) NOT NULL UNIQUE,
);
CREATE TABLE "Review" (
"ID" INT IDENTITY PRIMARY KEY,
"Name" NVARCHAR(1000) NOT NULL,
"Text" TEXT NOT NULL,
"Date" DateTime NOT NULL,
"Slug" NVARCHAR(200) NOT NULL,
"AmazonID" NVARCHAR(200) NOT NULL,
"UserID" INT FOREIGN KEY REFERENCES "User"(ID) NOT NULL
);
USE [master]
GO
CREATE LOGIN [dscrib2dev] WITH PASSWORD=N'backintime', DEFAULT_DATABASE=[DScrib2], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE [DScrib2]
GO
CREATE USER [dscrib2dev] FOR LOGIN [dscrib2dev]
GO
USE [DScrib2]
GO
ALTER USER [dscrib2dev] WITH DEFAULT_SCHEMA=[dbo]
GO
USE [DScrib2]
GO
EXEC sp_addrolemember N'db_owner', N'dscrib2dev'
GO
@mikedll
Copy link
Author

mikedll commented Oct 30, 2018

"How would I work with SQL Server 2008 with a .NET application without using Entity-Framework?"

One isn't really supposed to do this if EF suits you but it's nice to touch raw SQL with .NET at least once in one's life.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment