using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using iiie.Logs.DBO;
using iiie.WebApiUtils.DBO;
namespace iiie.WebApiUtils.BusinessManager
{
///
/// Helper for SQL Server data access
///
public abstract class SqlServerManager
: SqlServerBasicManager
where TDbObject : class
where TEntities : DbContext, new()
where TThis : SqlServerManager, new()
{
///
/// Convert a DB object to DBO
///
/// The object to be converted
/// The DBO
public abstract TDboGet DbToDboGet(TDbObject obj);
///
/// Convert a DBO to DB object
///
/// The object to be converted
/// The object to be added
/// The DB object
public abstract OpResult DboAddToDb(TDboAdd obj, TDbObject add);
///
/// Convert a DBO to DB object
///
/// The object to be converted
/// The object beeing edited
/// The DB object
public abstract OpResult DboEditToDb(TDboEdit obj, TDbObject edit);
///
/// Return a global predicate that will be applied to all selects
///
/// The expression
public virtual Expression> GetGlobalSelectPredicate()
{
return x => true;
}
///
/// Helper to get real select predicate
///
/// The global predicate
public static Expression> GetGlobalSelectPredicateStatic()
{
var obj = new TThis();
return obj.GetGlobalSelectPredicate();
}
///
/// Helper to convert DB object to DBO
///
/// The result to convert
/// The DBO object
public static TDboGet DbToDboGetStatic(TDbObject res)
{
var obj = new TThis();
return obj.DbToDboGet(res);
}
///
/// Helper to convert DBO object to DB
///
/// The result to convert
/// The object to be added
/// The DB object
public static OpResult DboAddToDbStatic(TDboAdd res, TDbObject add)
{
var obj = new TThis();
return obj.DboAddToDb(res, add);
}
///
/// Helper to convert DBO object to DB
///
/// The result to convert
/// The object beeing edited
/// The DB object
public static OpResult DboEditToDbStatic(TDboEdit res, TDbObject edit)
{
var obj = new TThis();
return obj.DboEditToDb(res, edit);
}
///
/// Get a single DB object matching the predicate
///
/// The table to search in
/// The predicate
/// The object that match
public static OpResult GetSingleDbObject(DbSet table, Expression> predicate)
{
var o = table.Where(GetGlobalSelectPredicateStatic()).FirstOrDefault(predicate);
if (o == null)
{
return OpResult.Error(ResultStatus.NotFound, typeof(TThis).Name + ": Value not found", "");
}
return OpResult.Ok(o);
}
///
/// Get a single DBO matching the predicate
///
/// The predicate
/// The object that match, or null
public static OpResult GetSingle(Expression> predicate)
{
return Execute((db, table) =>
{
var obj = GetSingleDbObject(table, predicate);
if (!obj)
return obj.To();
return OpResult.Ok(DbToDboGetStatic(obj.Data));
});
}
///
/// Get an object by its primary key(s)
///
/// The key names and values
/// The object
public static OpResult GetSingleByKeys(params KeyValuePair[] keys)
{
return GetSingle(GetExpression(keys));
}
///
/// Get an object by its id
///
/// The id of the object
/// The object
public static OpResult GetSingleById(long id)
{
return GetSingleByKeys(new KeyValuePair("id", id));
}
///
/// Get all DB object matching the predicate
///
/// The predicate
/// The order by function
/// The page numeber (0 based)
/// The maximum number of items par page
/// All matching objects
public static OpResult> GetMultiple(Expression> predicate,
Expression> orderBy, int page = 0, int perPage = Int32.MaxValue)
{
return Execute((db, table) =>
{
var globalPredicate = GetGlobalSelectPredicateStatic();
var count = table.Where(globalPredicate).Count(predicate);
var results = table.OrderBy(orderBy).Where(globalPredicate).Where(predicate)
.Skip(page * perPage).Take(perPage).Select(DbToDboGetStatic).ToList();
var result = new DboGetMultiple
{
Count = count,
Data = results
};
return OpResult>.Ok(result);
});
}
///
/// Get all DB object matching the predicate built from keys
///
/// The page numeber (0 based)
/// The maximum number of items par page
/// The order by function
/// The key names and values
/// All matching objects
public static OpResult> GetMultipleByKeys(Expression> orderBy,
int page = 0, int perPage = Int32.MaxValue, params KeyValuePair[] keys)
{
return GetMultiple(GetExpression(keys), orderBy, page, perPage);
}
///
/// Add an entry in the database
///
/// The object to be added
/// Used to return some data
/// The result defined by returnFunc
public static OpResult Add(TDboAdd obj, Expression> returnFunc)
{
return Execute((db, table) =>
{
var add = table.Create();
var item = DboAddToDbStatic(obj, add);
if (!item)
return item.To();
table.Add(add);
db.SaveChanges();
var res = returnFunc.Compile().DynamicInvoke(add);
return OpResult.Ok((T)res);
});
}
///
/// Add an entry in the database
///
/// The object to be added
/// Always true or an OpResult error
public static OpResult Add(TDboAdd obj)
{
return Add(obj, x => true);
}
///
/// Add an entry in the database
///
/// The object to be added
/// The DBO or an OpResult error
public static OpResult AddDbo(TDboAdd obj)
{
return Add(obj, x => DbToDboGetStatic(x));
}
///
/// Add an entry in the database
///
/// The object to be added
/// The DBO or an OpResult error
public static OpResult AddId(TDboAdd obj)
{
var param = Expression.Parameter(typeof(TDbObject), "x");
var exp = Expression.Property(param, "id");
var lambda = Expression.Lambda>(exp, param);
return Add(obj, lambda);
}
///
/// Edit an entry in the database
///
/// The object to be added
/// The predicate to be used to select data
/// Always true or an OpResult error
public static OpResult Edit(TDboEdit obj, Expression> predicate)
{
return Execute((db, table) =>
{
var edit = GetSingleDbObject(table, predicate);
if (!edit)
return edit.To();
var res = DboEditToDbStatic(obj, edit.Data);
if (!res)
return res.To();
db.Entry(edit.Data).CurrentValues.SetValues(edit.Data);
db.SaveChanges();
return OpResult.Ok(true);
});
}
///
/// Edit an entry in the database
///
/// The object to be added
/// The keys to be used to select data
/// Always true or an OpResult error
public static OpResult Edit(TDboEdit obj, params KeyValuePair[] keys)
{
return Edit(obj, GetExpression(keys));
}
///
/// Edit an entry in the database
///
/// The object to be added
/// The id to be edited
/// Always true or an OpResult error
public static OpResult EditById(TDboEdit obj, long id)
{
return Edit(obj, new KeyValuePair("id", id));
}
///
/// Delete an entry in the database
///
/// The predicate to be used to delete data
/// Always true or an OpResult error
public static OpResult Delete(Expression> predicate)
{
return Execute((db, table) =>
{
var del = GetSingleDbObject(table, predicate);
if (!del)
return del.To();
table.Remove(del.Data);
db.SaveChanges();
return OpResult.Ok(true);
});
}
///
/// Delete an entry in the database
///
/// The keys to be used to delete data
/// Always true or an OpResult error
public static OpResult Delete(params KeyValuePair[] keys)
{
return Delete(GetExpression(keys));
}
///
/// Delete an entry in the database
///
/// The id to be deleted
/// Always true or an OpResult error
public static OpResult DeleteById(long id)
{
return Delete(new KeyValuePair("id", id));
}
}
}