Hi Tim,
Here is an example console application I did last year to submit a bug report to Appeon. I can't remember what version of snap develop I used, but I know at the time it worked. It uses SqlExecutor and SqlModelMapper, but the database concepts are still the same. It uses two files DefaultDataContext.cs and Program.cs, but DefaultDataContext could have been replaced with SqlServerDataContext. I've just used a string to hardcode in the database connection string which connects to the AdventureWorks2012 database, but of course you could read that from a config file.
DefaultDataContext.cs
using System;
using SnapObjects.Data;
using SnapObjects.Data.SqlServer;
namespace ConsoleApp1
{
public class DefaultDataContext : SqlServerDataContext
{
public DefaultDataContext(string connectionString)
: this(new SqlServerDataContextOptions<DefaultDataContext>(connectionString))
{
}
public DefaultDataContext(IDataContextOptions<DefaultDataContext> options)
: base(options)
{
}
public DefaultDataContext(IDataContextOptions options)
: base(options)
{
}
}
}
Program.cs
using System;
using System.Linq;
using ConsoleApp1.Models;
using SnapObjects.Data;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string connection = "Data Source = localhost,1433; Initial Catalog = AdventureWorks2012; Integrated Security = True; Pooling = True; Min Pool Size = 0; Max Pool Size = 100; MultipleActiveResultSets = False; Encrypt = False; TrustServerCertificate = False; ApplicationIntent = ReadWrite";
var dataContext = new DefaultDataContext(connection);
ISqlQueryBuilder queryBuilder =
ModelSqlBuilder.GetBuilder<location>(dataContext).QueryBuilder;
// Show the original query
string sql = queryBuilder.ToSqlString(dataContext);
Console.WriteLine("Original Sql\r\n{0}'\r\n", sql);
// Run the original query
var executorResults = dataContext.SqlExecutor.Select<location>(queryBuilder).ToList();
var mapperResults = dataContext.SqlModelMapper.Load<location>(queryBuilder).ToList();
Console.WriteLine("SqlExecutor Records Returned = {0}", executorResults.Count());
Console.WriteLine("SqlModelMapper Records Returned = {0}\r\n", mapperResults.Count());
// Modify the query
queryBuilder.Where("location.locationid", SqlBinaryOperator.Equals, "7");
// Show the modified query
sql = queryBuilder.ToSqlString(dataContext);
Console.WriteLine("Modified Sql\r\n{0}\r\n", sql);
// Run the modified query
executorResults = dataContext.SqlExecutor.Select<location>(queryBuilder).ToList();
mapperResults = dataContext.SqlModelMapper.Load<location>(queryBuilder).ToList();
Console.WriteLine("SqlExecutor Records Returned = {0}", executorResults.Count());
Console.WriteLine("SqlModelMapper Records Returned = {0}", mapperResults.Count());
Console.ReadKey();
}
}
}
In an ASP.Net project the database data context is automagically made available through dependency injection. I think you can also implement dependency injection in a console application, but the easiest way is to create your database context in the main program and pass it into the objects you create via their constructor. Here is some code snippets which show what I mean.
// A class that uses a datacontext
public class ProcessingService
{
private readonly DefaultDataContext _dataContext;
public ProcessingService(DefaultDataContext dataContext)
{
_dataContext = dataContext;
}
public int DoSomething()
{
// Some code that does something with _dataContext
}
...... Other methods which use the _dataContect to get data from the database
}
// The main program which creates the datacontext
static void Main(string[] args)
{
string connection;
// get the connection string here (from config file)
var dataContext = new DefaultDataContext(connection);
ProcessingService process = new ProcessingService(dataContext);
var result = process.DoSomething();
// do something with the result
}