I have already searched for the error
the connection string property has not been initialized.
on Google as well as on Stack Overflow but couldn't find the solution. I have created a database class for interaction with database all related code is written in this file. The problem is same code runs fine on other pages and it just don't work on a page called "addevent.aspx" I don't understand the reason why it is not running properly.
Here are the methods that I created in database.cs file
public void CreateConnection()
{
var ConfiguredString = ConfigurationManager.ConnectionStrings[ConnectionString].ConnectionString;
obj_sqlconnection = new SqlConnection(ConfiguredString);
}
//This property will set the connection string for database
public string ConnectionString
{
get
{ //if _connectionString is already created or set, only then it will return the value of _connectionString
if (_connectionString != string.Empty && _connectionString != "" && _connectionString != null)
return _connectionString;
else
return string.Empty;
}
// When you want to set the connection string set block is called.
set
{ // this line sets the connection string to the _connectionString data member for the first time.
if (_connectionString == string.Empty || _connectionString == "" || _connectionString == null)
_connectionString = value;
}
}
// Open database connection.
public void OpenConnection()
{
obj_sqlconnection.Open();
}
// Close database connection.
public void CloseConnection()
{
obj_sqlconnection.Close();
obj_sqlconnection.Dispose();
}
public SqlConnection GetCurrentConnection
{
get { return obj_sqlconnection; }
set { obj_sqlconnection = value; }
}
I simply don't understand the logic of this error and its occurrence. I get this error when I open the connection
How do I call these methods, I have already created a object of database.cs class outside the method AddEvent with object name mydb
public int AddEvent(string _title, string _description, string _place, int _eventTypeID, string _startingTime, string _endingTime, string _startingDate, string _endingDate, string _creatorID, string _picture)
{
string[] blacklist = { _title, _description, _place, _picture };
if (Jvalidate.FilterBlackLIstKeywords(blacklist))
{
int eventid = Convert.ToInt32(mydb.GetLastValueByColumnName("event_id", "tbl_events"));
int rowsaffected = 0;
mydb.CreateConnection();
mydb.InitializeSQLCommandObject(mydb.GetCurrentConnection, "spAddEvent", true);
mydb.obj_sqlcommand.Parameters.AddWithValue("#eventID", eventid + 1);
mydb.obj_sqlcommand.Parameters.AddWithValue("#title", _title);
mydb.obj_sqlcommand.Parameters.AddWithValue("#description", _description);
mydb.obj_sqlcommand.Parameters.AddWithValue("#place", _place);
mydb.obj_sqlcommand.Parameters.AddWithValue("#eventType", _eventTypeID);
mydb.obj_sqlcommand.Parameters.AddWithValue("#startingTime", _startingTime);
mydb.obj_sqlcommand.Parameters.AddWithValue("#endingTime", _endingTime);
mydb.obj_sqlcommand.Parameters.AddWithValue("#startDate", _startingDate);
mydb.obj_sqlcommand.Parameters.AddWithValue("#endDate", _endingDate);
mydb.obj_sqlcommand.Parameters.AddWithValue("#schoolID", SchoolID);
mydb.obj_sqlcommand.Parameters.AddWithValue("#eventCreatorID", _creatorID);
mydb.obj_sqlcommand.Parameters.AddWithValue("#eventPicture", _picture);
try
{
//mydb.obj_sqlconnection.ConnectionString = ConfigurationManager.ConnectionStrings["cesConnectionString"].ToString();
mydb.OpenConnection();
rowsaffected = mydb.obj_sqlcommand.ExecuteNonQuery();
}
finally
{
mydb.CloseConnection();
mydb.obj_sqlcommand.Dispose();
}
return rowsaffected;
}
return 0;
}
it's too complicated solution... this will solve your problem of understanding and unnecessary code lines:
solution:
namespace Stackoverflow
{
public static class Solution
{
static readonly string _connectionStringName =
#"mainConnectionStringName";
static readonly string _connectionString =
_connectionStringName.getConnectionString();
// string extended method like .ToLower() or .Trim()
public static string getConnectionString(
this string connectionStringName)
{
return
System.
Configuration.
ConfigurationManager.
ConnectionStrings[connectionStringName].
ConnectionString;
}
public static object SqlExecute(
string connectionStringName,
string storedProcedureName,
System
.Collections
.Generic
.Dictionary<string, object> parameters,
bool isScalar)
{
object result = null;
using (System
.Data
.SqlClient
.SqlConnection connection =
new System.Data.SqlClient.SqlConnection(
string.IsNullOrWhiteSpace(connectionStringName)
? _connectionString
: connectionStringName.getConnectionString()))
if (connection != null)
using (System.Data.SqlClient.SqlCommand command =
new System.Data.SqlClient.SqlCommand()
{
CommandText = storedProcedureName,
CommandType = System
.Data
.CommandType
.StoredProcedure,
Connection = connection
})
if (command != null)
{
if (parameters != null)
foreach (System
.Collections
.Generic
.KeyValuePair<string, object>
pair in parameters)
command.Parameters.AddWithValue(
pair.Key, pair.Value);
command.Connection.Open();
result = isScalar
? command.ExecuteScalar()
: command.ExecuteNonQuery();
if (command.Connection.State ==
System.Data.ConnectionState.Open)
command.Connection.Close();
}
return result;
}
}
}
usage:
namespace SomeNamespace
{
public sealed class SomeClass
{
public int Example()
{
return (int)Stackoverflow
.Solution
.SqlExecute(
#"anyConnectionStringName", // or null for main connection string
#"anyStoredProcedureName",
new System
.Collections
.Generic
.Dictionary<string, object>()
{
{ #"field0", "value" },
{ #"field1", -1.5 },
{ #"field2", System.DateTime.Now },
{ #"field3", 3.5 },
{ #"field4", 7 },
},
false // for ExecuteNonQuery or true for ExecuteScalar
);
}
}
}
Related
I have a WinForms application that gets Car data from a Sqlite database file which is generated by a CSV file from a WebService, and the related Parts for each Car. When instanced, the Car class populates all properties from the database and gets a lot of data from a WebService that takes about 30 seconds to finish so I just call an async Task after populating the database properties and let it run asyncronously. After the web service returns all data and all work is done, the instance is saved in a List that works like an internal cache.
All works well until the user makes an operation on a Part which requires the property ParentCar to be returned while the WebService method is still running, causing a new Car to be instantiated and re polling the web service as many times the property is requested while the Car doesn't exist on the cache list. This stops as soon as the first instance finishes processing but all changes will be overwritten every time the next instances finish.
I'm struggling to find a way to ensure that a Car is only instanced one time without blocking the UI during the application life time, any ideas?
This is the code that I currently have:
public class Car
{
private List<Part> _parts = new List<Part>();
public string Id { get; private set; }
public int DbIndex
{
get { return DbClass.GetCarIndexById(Id); }
}
public ReadOnlyCollection<Part> Parts { get => _parts.AsReadOnly(); }
public Car(System.Data.SQLite.SQLiteDataReader sQLiteDataReader)
{
// Code to Load all properties from sQLiteDataReader
Task.Run(() => LongRuningWebServiceTask());
}
private async Task LongRuningWebServiceTask
{
// Long running code that will populate even more properties
SaveToInternalDb();
}
private void SaveToInternalDb()
{
if (DbIndex > -1)
DbClass.UpdateCarData(this);
else
DbClass.AddCar(this);
}
public void RelateParts(IEnumerable<Part> parts)
{
_parts.AddRange(parts);
}
~Car()
{
SaveToInternalDb();
}
}
public class Part
{
public string ParentCarId { get; private set; }
public Car ParentCar
{
get
{
Task getCar = DbClass.GetCarById(ParentCarId);
getCar.Wait();
return getCar.Result;
}
}
}
public static class DbClass
{
private static SQLiteConnection sqlConn;
private readonly string sqlFile = "pathToDbFile";
private static List<Car> CarCache = new List<Car>();
public static async Task<Car> GetCarById(string> carId, bool ignoreCache = false)
{
Car foundCar = null;
if (!ignoreCache)
foundCar = CarCache.Find(s => s.Id == carId);
if (foundCar == null)
{
try
{
string sql = string.Format("SELECT * FROM all_Cars WHERE Car = '{0}';", carId);
using (SQLiteCommand command = new SQLiteCommand(sql, sqlConn))
{
using (SQLiteDataReader reader = (SQLiteDataReader)await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
foundCar = new Car(reader));
}
}
}
catch (Exception e)
{
string m = e.Message;
}
if (foundCar != null)
{
var partsList = await GetPartsByCarId(carId);
if (partsList.Count > 0)
Car.RelateParts(partsList);
if (!ignoreCache)
{
if (foundCar.DbIndex == -1)
CarCache.Add(foundCar);
}
}
}
return foundCar;
}
public static async Task<List<Part>> GetPartsByCarId(string carId)
{
List<Part> foundParts = new List<Part>();
int index = GeCarIndexById(carId);
Car foundCar = index > -1 ? CarCache[index] : null;
if (foundCar != null)
foundParts = await GetPartsByCarId(carId);
return foundParts;
}
public static void InitiateSqlConnection()
{
if (sqlConn == null)
{
sqlConn = new SQLiteConnection("Data Source=" + sqlFile.FullName + ";Version=3;");
try
{
sqlConn.Open();
}
catch (Exception e)
{
var m = e.Message;
}
}
else
{
if(sqlConn.State == System.Data.ConnectionState.Broken || sqlConn.State == System.Data.ConnectionState.Closed)
sqlConn.Open();
}
}
public static int GetCarIndexById(string carId)
{
int index = -1;
for(int c = 0; c < CarCache.Count;c++)
{
if(CarCache[c].Id == carId)
{
index = c;
break;
}
}
return index;
}
public static void AddCar(Car car)
{
CarCache.Add(car);
}
public static void UpdateCarData(Car car)
{
if(car != null)
{
int index = car.DbIndex;
if(index > -1)
CarCache[index] = car;
}
}
}
I'm getting an odd issue where I'm able to return results from a call to a stored procedure, but the code retrospectively fails.
public IEnumerable<T> ExecuteStoredProcedure<T>(string storedProcedureName, IDataMapper<T> mapper, IDictionary<string, object> parameters)
{
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(storedProcedureName, connection))
{
cmd.CommandType = CommandType.StoredProcedure;
foreach (var key in parameters.Keys)
{
cmd.Parameters.AddWithValue(key, parameters[key]);
}
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
//return MapRecordsToDTOs(reader, mapper);
//let's test:
IEnumerable<T> result = MapRecordsToDTOs(reader, mapper);
var x = (new List<T>(result)).Count;
System.Diagnostics.Debug.WriteLine(x);
return result;
}
}
}
private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
if (reader.HasRows)
{
while (reader.Read())
{
System.Diagnostics.Debug.WriteLine(reader["Id"]); //what's going on...
yield return mapper.MapToDto((IDataRecord)reader);
}
}
}
Calling this code shows that variable x always represents the number of rows I'd expect to see from a call to my stored procedures.
Additionally my debug output shows the ID values I'd expect to see.
However, after those results are returned, I get the error An exception of type 'System.InvalidOperationException' occurred in System.Data.dll but was not handled in user code from the line if (reader.HasRows) (i.e. which has already been executed). The browser from which I invoke this request shows HTTP Error 502.3 - Bad Gateway.
I suspect the reason is the system's calculating the ID and X values for debug separately to how it would return the real user output. As such, it performs a lazy operation to get the IEnumerable values at the point at which it has to return them; only by this point the using statements have caused the dispose methods to be called, and thus the reader's connection is null (this is what I see when I inspect the reader variable's properties whilst debugging).
Has anyone seen behaviour like this before / is it a bug; or have I just missed something obvious?
Additional Code:
public interface IDataMapper<T>
{
T MapToDto(IDataRecord record);
}
public class CurrencyMapper: IDataMapper<CurrencyDTO>
{
const string FieldNameCode = "Code";
const string FieldNameId = "Id";
const string FieldNameName = "Name";
const string FieldNameNum = "Num";
const string FieldNameE = "E";
const string FieldNameSymbol = "Symbol";
public CurrencyMapper() { }
public CurrencyDTO MapToDto(IDataRecord record)
{
var code = record[FieldNameCode] as string;
var id = record[FieldNameId] as Guid?;
var name = record[FieldNameName] as string;
var num = record[FieldNameNum] as string;
var e = record[FieldNameE] as int?;
var symbol = record[FieldNameSymbol] as char?;
return new CurrencyDTO(id, code, num, e, name, symbol);
}
}
public class CurrencyRepository
{
const string SPReadAll = "usp_CRUD_Currency_ReadAll";
readonly SqlDatabase db;
public CurrencyRepository()
{
db = new SqlDatabase(); //stick to SQL only for the moment for simplicity
}
public IEnumerable<CurrencyDTO> GetCurrencyCodes()
{
var mapper = new CurrencyMapper();
return db.ExecuteStoredProcedure(SPReadAll, mapper);
}
}
public class CurrencyDTO
{
readonly Guid? id;
readonly string code;
readonly string num;
readonly int? e;
readonly string name;
readonly char? symbol;
public CurrencyDTO(Guid? id,string code,string num,int? e,string name, char? symbol)
{
this.id = id;
this.code = code;
this.num = num;
this.e = e;
this.name = name;
this.symbol = symbol;
}
public Guid? Id { get { return id; } }
public string Code { get { return code; } }
public string Num { get { return num; } }
public int? E { get { return e; } }
public string Name { get { return name; } }
public char? Symbol { get { return symbol; } }
}
I've temporarily implemented a workaround which resolves this issue.
This works:
private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
var list = new List<T>(); //use a list to force eager evaluation
if (reader.HasRows)
{
while (reader.Read())
{
list.Add(mapper.MapToDto((IDataRecord)reader));
}
}
return list.ToArray();
}
As opposed to the original:
private static IEnumerable<T> MapRecordsToDTOs<T>(SqlDataReader reader, IDataMapper<T> mapper)
{
if (reader.HasRows)
{
while (reader.Read())
{
yield return mapper.MapToDto((IDataRecord)reader);
}
}
}
The difference being I move the code affected by the iterator such that it only iterates through the results in the list; and doesn't rely on the compiler sensibly understanding the requirements related to IDisposable objects.
It's my understanding that the compiler should be able to handle this for me (confirmed here: https://stackoverflow.com/a/13504789/361842), so I suspect it's a bug in the compiler.
Reported here: https://connect.microsoft.com/VisualStudio/feedback/details/3113138
Additional demo code here:
https://gist.github.com/JohnLBevan/a910d886df577e442e2f5a9c2dd41293/
I copied the ConnectString value from the properties of my local database.
Connection String from the properties is :
Data Source=Cyber\SQLEXPRESS;Initial Catalog=GeneratedData;Integrated Security=True;
When I directly copy the ConnectionString into ConnectString, I get an error. So I take that "\" off and I did not get an error. However it still does not work. I also noticed that people usually change that ConnectionString value to a single word to make it easy.However, my VB properties section is not allowing me to change it. Here is the error I get
public class SQLConnection
{
#region MemberVariables
private SqlConnection mConnection = null;
private SqlDataAdapter mDataAdapter = null;
private SqlCommand mCommand = null;
static string mDbConnString = string.Empty;
#endregion
#region PublicMemberVariables
public SqlConnection Connection
{
get
{
return mConnection;
}
set
{
mConnection = value;
}
}
public SqlDataAdapter DataAdapter
{
get
{
return mDataAdapter;
}
set
{
mDataAdapter = value;
}
}
public SqlCommand Command
{
get
{
return mCommand;
}
set
{
mCommand = value;
}
}
public string ConnectString
{
get
{
return mDbConnString;
}
set
{
lock (mDbConnString)
{
mDbConnString = value;
}
lock (mConnection)
{
mConnection.ConnectionString = mDbConnString;
}
}
}
#endregion
public void TestConnection()
{
ConnectString = "Data Source=Cyber SQLEXPRESS;Initial Catalog=GeneratedData;Integrated Security=True";
Connection = new SqlConnection(ConnectString);
Connection.Open();
MessageBox.Show(Connection.State.ToString());
}
}
Change
Data Source=Cyber\SQLEXPRESS;Initial Catalog=GeneratedData;Integrated Security=True;
To
Data Source=Cyber\\SQLEXPRESS;Initial Catalog=GeneratedData;Integrated Security=True;
How can i sign-out and redirect to the login page from a public static class?
I have tried the following but it does not stop page execution..
public static DatabaseNameEntities CreateEntitiesForSpecificDatabaseName(bool contextOwnsConnection = true)
{
string database_name = "";
try
{
database_name = System.Web.HttpContext.Current.Application["DB_NAME"].ToString();
}
catch (NullReferenceException)
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
}
//Initialize the SqlConnectionStringBuilder
//Initialize the EntityConnectionStringBuilder
//Create entity connection
EntityConnection connection = new EntityConnection(entityBuilder.ConnectionString);
return new DatabaseNameEntities(connection);
}
I have tried the following but it does not stop page execution..
That's because it's simply not the MVC way. It's also breaks the Single Responsibility Principle, that is, why would a method named CreateEntitiesForSpecificDatabaseName() know anything about MVC or logging out a user. The code you posted generally breaks this principle multiple times (application state, signing out a user).
Additionally, catching an exception you can prevent is also poor practice (or as the Lead Developer for the C# Compiler team called it, Boneheaded Exceptions).
Consider the following code.
public static ControllerBaseExtensions
{
private const string DBNAME = "DB_NAME";
public static bool TryGetDatabaseName(this ControllerBase instance,
out string DbName)
{
DbName = null;
var app = GetApp(instance);
var result = app.Any(k => k == DBNAME);
if (result)
{
DbName = instance.Application[DBNAME] as string;
result = DbName != null;
}
return result;
}
public static void SetDatabaseName(this ControllerBase instance,
string DbName)
{
var app = GetApp(instance);
app[DBNAME] = DbName;
}
private static HttpApplication GetApp(ControllerBase instance)
{
return instance.ControllerContext.HttpContext.Application;
}
}
public ActionResult MyMethod()
{
string DbName;
if (!this.TryGetDatabaseName(out DbName))
{
FormsAuthentication.SignOut();
// http://stackoverflow.com/questions/30509980
RedirectToAction("Login", "Account");
}
CreateEntitiesForSpecificDatabaseName(Dbname);
}
public static DatabaseNameEntities CreateEntitiesForSpecificDatabaseName(
string dbName,
bool contextOwnsConnection = true)
{
//Initialize the SqlConnectionStringBuilder
//Initialize the EntityConnectionStringBuilder
//Create entity connection
EntityConnection connection = new
EntityConnection(entityBuilder.ConnectionString);
return new DatabaseNameEntities(connection);
}
Does simply ie, no try or catch work as expected
public static DatabaseNameEntities CreateEntitiesForSpecificDatabaseName(bool contextOwnsConnection = true)
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
}
See my repository code
public abstract class AdoRepository<T> where T : class
{
private static SqlConnection _connection;
public AdoRepository(string connectionString)
{
_connection = new SqlConnection(connectionString);
}
public virtual T PopulateRecord(SqlDataReader reader)
{
return null;
}
public virtual void GetDataCount(int count)
{
}
protected IEnumerable<T> GetRecords(SqlCommand command)
{
var list = new List<T>();
command.Connection = _connection;
_connection.Open();
try
{
var reader = command.ExecuteReader();
try
{
while (reader.Read())
{
list.Add(PopulateRecord(reader));
}
reader.NextResult();
if (reader.HasRows)
{
while (reader.Read())
{
GetDataCount(Convert.ToInt32(reader["Count"].ToString()));
}
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
catch(Exception ex)
{
string Msg = ex.Message;
}
finally
{
_connection.Close();
}
return list;
}
protected T GetRecord(SqlCommand command)
{
T record = null;
command.Connection = _connection;
_connection.Open();
try
{
var reader = command.ExecuteReader();
try
{
while (reader.Read())
{
record = PopulateRecord(reader);
break;
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
finally
{
_connection.Close();
}
return record;
}
protected IEnumerable<T> ExecuteStoredProc(SqlCommand command)
{
var list = new List<T>();
command.Connection = _connection;
command.CommandType = CommandType.StoredProcedure;
_connection.Open();
try
{
var reader = command.ExecuteReader();
try
{
while (reader.Read())
{
var record = PopulateRecord(reader);
if (record != null) list.Add(record);
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
finally
{
_connection.Close();
}
return list;
}
}
public class StudentRepository : AdoRepository<Student>
{
public int DataCounter { get; set; }
public StudentRepository(string connectionString)
: base(connectionString)
{
}
public IEnumerable<Student> GetAll()
{
// DBAs across the country are having strokes
// over this next command!
using (var command = new SqlCommand("SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents"))
{
return GetRecords(command);
}
}
public Student GetById(string id)
{
// PARAMETERIZED QUERIES!
using (var command = new SqlCommand("SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents WHERE Id = #id"))
{
command.Parameters.Add(new ObjectParameter("id", id));
return GetRecord(command);
}
}
public IEnumerable<Student> GetStudents(int StartIndex, int EndIndex, string sortCol, string sortOrder)
{
string strSQL = "SELECT * FROM vwListStudents WHERE ID >=" + StartIndex + " AND ID <=" + EndIndex;
strSQL += " ORDER BY " + sortCol + " " + sortOrder;
strSQL += ";SELECT COUNT(*) AS Count FROM vwListStudents";
var command = new SqlCommand(strSQL);
return GetRecords(command);
}
public override Student PopulateRecord(SqlDataReader reader)
{
return new Student
{
ID = Convert.ToInt32(reader["ID"].ToString()),
FirstName = reader["FirstName"].ToString(),
LastName = reader["LastName"].ToString(),
IsActive = Convert.ToBoolean(reader["IsActive"]),
StateName = reader["StateName"].ToString(),
CityName = reader["CityName"].ToString()
};
}
public override void GetDataCount(int count)
{
DataCounter = count;
}
}
this way unit of work code added
public class UnitOfWorkFactory
{
public static IUnitOfWork Create()
{
var connection = new SqlConnection(ConfigurationManager.ConnectionStrings("MyDb").ConnectionString);
connection.Open();
return new AdoNetUnitOfWork(connection, true);
}
}
public class AdoNetUnitOfWork : IUnitOfWork
{
public AdoNetUnitOfWork(IDbConnection connection, bool ownsConnection)
{
_connection = connection;
_ownsConnection=ownsConnection;
_transaction = connection.BeginTransaction();
}
public IDbCommand CreateCommand()
{
var command = _connection.CreateCommand();
command.Transaction = _transaction;
return command;
}
public void SaveChanges()
{
if (_transaction == null)
throw new InvalidOperationException("Transaction have already been commited. Check your transaction handling.");
_transaction.Commit();
_transaction = null;
}
public void Dispose()
{
if (_transaction != null)
{
_transaction.Rollback();
_transaction = null;
}
if (_connection != null && _ownsConnection)
{
_connection.Close();
_connection = null;
}
}
}
using (var uow = UnitOfWorkFactory.Create())
{
var repos = new UserRepository(uow);
uow.SaveChanges();
}
public class UserRepository
{
private AdoNetUnitOfWork _unitOfWork;
public UserRepository(IUnitOfWork uow)
{
if (uow == null)
throw new ArgumentNullException("uow");
_unitOfWork = uow as AdoNetUnitOfWork;
if (_unitOfWork == null)
throw new NotSupportedException("Ohh my, change that UnitOfWorkFactory, will you?");
}
public User Get(Guid id)
{
using (var cmd = _unitOfWork.CreateCommand())
{
cmd.CommandText = "SELECT * FROM Users WHERE Id = #id");
cmd.AddParameter("id", id);
// uses an extension method which I will demonstrate in a
// blog post in a couple of days
return cmd.FirstOrDefault<User>();
}
}
}
but i want to add unit of work code in my repository class. may be in AdoRepository class or StudentRepository class as a result i do not have to write the below code again and again.
using (var uow = UnitOfWorkFactory.Create())
{
var repos = new UserRepository(uow);
uow.SaveChanges();
}
so when i will be working with any repository like UserRepository then i have to repeat again and again this lines of code UnitOfWorkFactory.Create() which i do not want rather i am looking for a way to embed unit of work code in some where centralize as a result i could reduce the repeated code.
so looking for idea and suggestion. if possible give me modified version of code.
thanks
I will be straightforward about this:
A UoW that contains repositories is an anti pattern at least if DDD is involved. If it isn't, then you're dealing with a very simple app so make you life easier and use a ORM which implements what you want.
As a thumb rule, a repository may contain a UoW as an implementation detail and you should be certain that you really need a repository. A repository inside a UoW is a very specific case which is valid ONLY with CRUD apps and you'll just be reinventing a very small part of an ORM.
Using ado.net directly is wasting time (and money). Either use an ORM or a data mapper aka micro-ORM. With the latter option the UoW is the Db transaction.
You don't gain anything significant using Ado.Net,the performance gain is so small it's not even funny (I know that because I've benchmarked it). The only thing you'll get is longer devel time and human errors.
Actually, if I take a better look at your code, you're basically building a micro ORM, without knowing it. It's still not a repository though, because the abstraction doesn't have business semantics and it's too tightly coupled to an implementation detail.