728x90
쿼리에 들어가는 파라미터 변수와 값을 매핑하는 메소드
DAC에서 DB Helper쪽으로 Insert Qeury를 자동 생성 하는 메소드 호출
7년 전 자전거 GPS Logger Viewer 만들면서 짰던 DB Helper 코드
다양한 관계형(RDMS)에 DB에 대응할 수 있으며 개인 용도로 사용했던 db는 Sqlite다.
포터블 DB이며 가볍고 장점이 많다.
모델 속성(Field)을 테이블 컬럼명과 동일하게 만들면 자동으로 Insert 쿼리를 생성 해준다.
객체의 속을 들여다 볼 수 있는 Refelection을 사용하여 속도가 느린 단점이 있어 대용량 데이터를 처리하기에는
성능이 저하될 수 있다.
(트랜잭션 코드 추가)
using System;
using System.Data;
using System.Configuration;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data.Odbc;
using System.Data.SQLite.EF6;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.ComponentModel;
using System.Text;
using System.Linq;
using System.Data.SQLite;
using System.Reflection;
using System.IO;
using System.Windows.Forms;
namespace GpsLogManager.Common
{
public class DBHelper : IDisposable
{
private DbProviderFactory _factory = null;
private DbProviders _provider;
public DBHelper(DbProviders provider)
{
CreateDBObjects(provider);
}
private string _connectionstring = string.Empty;
public string ConnectionString
{
get { return _connectionstring; }
set
{
if (value != "")
_connectionstring = value;
}
}
private DbConnection _connection;
public DbConnection Connection
{
get { return _connection; }
set { _connection = value; }
}
private DbCommand _command;
public DbCommand Command
{
get { return _command; }
}
public string GetConnectionString()
{
//ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
ConnectionString = string.Format(@"Data Source={0}\xxxxxx.db;Version=3;", Application.StartupPath);
return ConnectionString;
}
public void CreateDBObjects(DbProviders provider)
{
_provider = provider;
switch (provider)
{
case DbProviders.SqlServer:
_factory = SqlClientFactory.Instance;
break;
case DbProviders.Oracle:
break;
case DbProviders.OleDb:
_factory = OleDbFactory.Instance;
break;
case DbProviders.ODBC:
_factory = OdbcFactory.Instance;
break;
case DbProviders.SQLite:
_factory = SQLiteProviderFactory.Instance;
break;
case DbProviders.SqlCe:
_factory = SqlCeProviderFactory.Instance;
break;
}
_connection = _factory.CreateConnection();
_command = _factory.CreateCommand();
_connection.ConnectionString = GetConnectionString();
_command.Connection = Connection;
}
public int AddParameter(string name, object value)
{
DbParameter param = _factory.CreateParameter();
param.ParameterName = name;
param.Value = value;
return Command.Parameters.Add(param);
}
public void ClearParameter()
{
if (_command != null && _command.Parameters.Count > 0)
_command.Parameters.Clear();
}
public void BeginTransaction()
{
if (Connection.State == ConnectionState.Closed)
Connection.Open();
Command.Transaction = Connection.BeginTransaction();
}
public void CommitTransaction()
{
Command.Transaction.Commit();
Connection.Close();
}
private void RollbackTransaction()
{
Command.Transaction.Rollback();
Connection.Close();
}
public int ExecuteNonQuery(string query, CommandType commandType, List<DbParameter[]> listParameters)
{
int i = -1;
Command.CommandType = commandType;
Command.CommandText = query;
try
{
if(Connection.State == ConnectionState.Closed)
Connection.Open();
BeginTransaction();
if (listParameters.Count > 0)
{
for (int k = 0; k < listParameters.Count; k++)
{
foreach (DbParameter param in listParameters[k])
{
AddParameter(param.ParameterName, param.Value);
}
i = Command.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
RollbackTransaction();
throw (ex);
}
finally
{
CommitTransaction();
ClearParameter();
if (Connection.State == ConnectionState.Open)
{
Connection.Close();
Connection.Dispose();
}
}
return i;
}
public List<T> ExecuteReader<T>(string query, CommandType commandType)
{
List<T> rtnList = new List<T>();
Command.CommandType = commandType;
Command.CommandText = query;
try
{
Connection.Open();
rtnList = GetListFromDataReader<T>(Command.ExecuteReader());
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (Connection.State == ConnectionState.Open)
{
Command.Dispose();
Connection.Close();
Connection.Dispose();
}
}
return rtnList;
}
public void AutoMakeParamseter<T>(string query, List<T> list)
{
PropertyDescriptorCollection property = GetPropetyDescriptorInfo<T>();
List<DbParameter[]> listParameter = new List<DbParameter[]>();
foreach (T item in list)
{
DbParameter[] parameters = new DbParameter[property.Count];
for (int i = 0; i < property.Count; i++)
{
PropertyDescriptor prop = property[i];
parameters[i] = new SqlParameter("@"+ prop.Name, prop.PropertyType);
parameters[i].Value = property[i].GetValue(item);
}
listParameter.Add(parameters);
}
ExecuteNonQuery(query, CommandType.Text, listParameter);
}
public string AddIn(List<string> list)
{
string rtnAddin = string.Empty;
if (list.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string s in list)
sb.AppendFormat(" '{0}', ", s);
int lastComma = sb.ToString().LastIndexOf(',');
if (!string.IsNullOrEmpty(sb.ToString()))
sb.Remove(lastComma, 1);
rtnAddin = sb.ToString();
}
return rtnAddin;
}
public string InsertAutoQuery<T>(string tableName)
{
PropertyDescriptorCollection props = GetPropetyDescriptorInfo<T>();
StringBuilder sbParameter = new StringBuilder();
StringBuilder sbValue = new StringBuilder();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
if (!prop.Name.Equals("OVERLAP"))
{
sbParameter.AppendFormat(" {0}, ", prop.Name);
sbValue.AppendFormat("@{0}, ", prop.Name);
}
}
sbParameter.Remove(sbParameter.ToString().LastIndexOf(','), 1);
sbValue.Remove(sbValue.ToString().LastIndexOf(','), 1);
string query = string.Format(@" INSERT INTO {0} ({1}) VALUES ({2}); ", tableName, sbParameter, sbValue);
return query;
}
public Dictionary<string, string> DBColumn<T>(T item)
{
Dictionary<string, string> dbMappings = new Dictionary<string, string>();
var type = item.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
var attributes = property.GetCustomAttributes(false);
var columnMapping = attributes.FirstOrDefault(a => a.GetType() == typeof(DbColumnAttribute));
if (columnMapping != null)
{
dbMappings.Add(property.Name, ((DbColumnAttribute)columnMapping).Name);
}
}
return dbMappings;
}
public List<T> GetListFromDataReader<T>(IDataReader reader)
{
List<T> rtnList = new List<T>();
var properties = typeof(T).GetProperties();
var columnList = (reader.GetSchemaTable().Select()).Select(r => r.ItemArray[0].ToString());
while (reader.Read())
{
var element = Activator.CreateInstance<T>();
Dictionary<string, string> dbMappings = DBColumn(element);
string columnName;
foreach (var f in properties)
{
if (!columnList.Contains(f.Name) && !dbMappings.ContainsKey(f.Name))
continue;
columnName = dbMappings.ContainsKey(f.Name) ? dbMappings[f.Name] : f.Name;
var o = (object)reader[columnName];
if (o.GetType() != typeof(DBNull))
f.SetValue(element, ChangeType(o, f.PropertyType), null);
}
rtnList.Add(element);
}
reader.Close();
return rtnList;
}
public object ChangeType(object value, Type conversion)
{
var t = conversion;
if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
t = Nullable.GetUnderlyingType(t);
}
return Convert.ChangeType(value, t);
}
public PropertyDescriptorCollection GetPropetyDescriptorInfo<T>()
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
return props;
}
public void Dispose()
{
throw new NotImplementedException();
}
public enum DbProviders
{
Oracle,
MySql,
ORM,
Dapper,
NPoco,
SqlServer,
PostgreSQL,
SQLite,
NoSQL,
MongoDB,
RavenDB,
Redis,
Cassandra,
CouchBase,
CouchDB,
Neo4j,
YesSql,
LuceneNET,
OleDb,
ODBC,
NpgSql,
SqlCe
}
}
public class DbColumnAttribute : Attribute
{
public string Name { get; set; }
public DbColumnAttribute(string _name)
{
this.Name = _name;
}
public DbColumnAttribute()
: this(null) { }
}
}
예제로 넣은 엔티티 클래스
using System;
namespace GpsLogManager.Field
{
/// <summary>
/// gpslog 클래스
/// </summary>
public class GpsLogData
{
public GpsLogData() { }
public GpsLogData(string title, double lat, double lng, double ele)
{
this.TITLE = title;
this.LAT = lat;
this.LNG = lng;
this.ELE = ele;
}
public string DAY_SEQ { get; set; }
public string RIDE_DATE { get; set; }
public string TITLE { get; set; }
public double LAT { get; set; }
public double LNG { get; set; }
public double ELE { get; set; }
public double SPEED_KMH { get; set; }
public double KM { get; set; }
public double DIFF_TIME { get; set; }
public string LOG_TIME { get; set; }
public string LOG_TIME_ORIGEN { get; set; }
public double ATEMP { get; set; }
public double CAD { get; set; }
public double HEART { get; set; }
public string RIDE_DATE_ORIGEN { get; set; }
public string WAYPOINT { get; set; }
public string OVERLAP { get; set; } // DB 중복체크
}
}
'.NET C#' 카테고리의 다른 글
c# 자전거 라이딩 거리 계산 관련 Utils (0) | 2023.01.13 |
---|---|
c# DateTime (날짜, 시간, 요일 추출) Utils (0) | 2023.01.13 |
C# GPX(GPS Exchange Format) Paser (0) | 2023.01.13 |
시작일과 종료일 기간 체크 및 날짜 등분 (0) | 2012.05.05 |
시작과 종료일 날짜 간격 구하는 로직 (0) | 2012.05.03 |
Visual Studio 2010 and .NET Framework 4.0 Training Kit - November Preview (0) | 2008.11.30 |
SQL 2008 설치전 몇가지 고려사항 (0) | 2008.11.25 |
댓글