I have this situation:
private static EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>();
private List<Set> SplitBySetId(List<Step> stepList)
{
List<Set> outputSetList = new List<Set>();
using (entityBuilderCore)
{
stepList.ForEach(step =>
{
// For each step, I find the corrispectives set's ids (one or more).
// Then, I create the Set
List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);
// Create Sets and adding to the output list
setIdList.ToList().ForEach(id =>
{
if (!outputSetList.Any(set => set.Id == id))
outputSetList.Add((Set)entityBuilderCore.GetEntity(typeof(Set), id));
});
});
}
return outputSetList;
}
But I can have A LOT of steps subdivided in many Set... so I was thinking to parallelizate in this way (looks the add part):
private List<Set> SplitBySetId(List<Step> stepList)
{
List<Set> outputSetList = new List<Set>();
using (entityBuilderCore)
{
stepList.ForEach(step =>
{
// For each step, I find the corrispectives set's ids (one or more).
// Then, I create the Set
List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);
// Create Sets and adding to the output list
var tempList = setIdList.Distinct()
.AsParallel()
.Where(id => !outputSetList.Any(set => set.Id == id))
.Select(setId => (Set)entityBuilderCore.GetEntity(typeof(Set), setId));
outputSetList.AddRange(tempList);
});
}
return outputSetList;
}
But I'm not sure about the thread-safety of the entityBuilderCore. The core is this:
class EntityBuilderCore : CoreBase
{
private static EntityRepository Repository;
protected override string _connectionString
{
get { return ConfigurationService.Instance.GetValue("connessione_database_sinistriweb"); }
}
private EntityBuilderCore()
{
Repository = new EntityRepository() { ConnectionString = _connectionString };
}
public BaseEntity GetEntity(Type entityType, int id)
{
return EntityBuilder.BuildEntity(entityType, Repository.GetEntity(entityType, id));
}
// ...
public List<int> GetSetIdByStep(Step step)
{
return Repository.GetSetIdByStep(step);
}
}
class EntityRepository : RepositoryBase
{
Dictionary<Type, string> tableDictionary = new Dictionary<Type, string>();
public EntityRepository()
{
tableDictionary.Add(typeof(SQL), "PROCESSI.DBO.GFE_SQL");
tableDictionary.Add(typeof(Step), "PROCESSI.DBO.GFE_STEP");
tableDictionary.Add(typeof(StepSet), "PROCESSI.DBO.GFE_SET");
}
public DataRow GetEntity(Type systemType, int id)
{
string entityTable;
tableDictionary.TryGetValue(systemType, out entityTable);
using (SqlConnection connection = new SqlConnection(ConnectionString))
using (SqlCommand command = new SqlCommand(string.Format("SELECT * FROM {0} WHERE ID = #ID", entityTable), connection))
{
connection.Open();
command.Parameters.Add("#ID", System.Data.SqlDbType.Int).Value = id;
using (SqlDataReader dr = command.ExecuteReader())
{
if (dr.Read())
{
DataTable entityDataTable = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
connection.Close();
dataAdapter.Fill(entityDataTable);
return entityDataTable.Rows[0];
}
}
}
return null;
}
public List<int> GetSetIdByStep(Step step)
{
// bla bla
}
// ...
}
I will prefer to use only ONE entityBuilderCore also in the EntityBuilder class. I prefer to not instantiate every time the entityBuilderCore, I think is useless. But I'm afraid is not thread safety, because the SplitBySetId method is used by many Tasks at the same time
class EntityBuilder
{
public static BaseEntity BuildEntity(Type entityType, DataRow dr)
{
if (entityType == typeof(SQL))
return BuildSQL(dr);
if (entityType == typeof(Step))
return BuildStep(dr);
if (entityType == typeof(Set))
return BuildSet(dr);
return null;
}
//...
private static Step BuildStep(DataRow dr)
{
using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
{
Step s = new Step()
{
Id = Convert.ToInt16(dr["ID"]),
//... bla bla
};
return s;
}
}
private static Set BuildSet(DataRow dr)
{
using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
{
Set s = new Set()
{
Id = Convert.ToInt16(dr["ID"]),
//...
};
return s;
}
}
}
Related
There are only 3 situations for result.
1- Paid
2- waiting for payment
3- blocked
(Think like this is a bank program)
So when I run the code, always says true. Never false. I want it work normally. Need help.
[HttpPut(Name = "OdemeYapildiSosyalOdeme")]
public ActionResult<bool> Put(string tckn, int odemeNo)
{
try
{
DbOperations dbOperations = new DbOperations();
var parameters = new List<SqlParameter>();
var param1 = new SqlParameter("TCKN", tckn);
parameters.Add(param1);
var param2 = new SqlParameter("ODEMENO", odemeNo);
parameters.Add(param2);
if (odemeKd == 0)
{
dbOperations.ExecuteNonQuery("ODEME_YAP", parameters);
return Ok(true);
}
else return Ok(false);
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SosyalYardimApi.Operations;
using System.Data.SqlClient;
using System.Data;
namespace SosyalYardimApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SosyalOdemeController : ControllerBase
{
private int odemeKd;
private object sosyalOdemeleri;
public bool Boolean { get; private set; }
[HttpGet(Name = "SorgulaSosyalOdeme ")]
public ActionResult<List<SosyalOdeme>> Get(string tckn)
{
try
{
//Yapılacak: Tckn 11 karakterli mi kontrolü yapılacak değilse dönüş olacak,
//return Ok("TCKN Hatalı");
if (tckn.Length == 11)
{
List<SosyalOdeme> sosyalOdemeleri = new List<SosyalOdeme>();
DbOperations dbOperations = new DbOperations();
var parameters = new List<SqlParameter>();
var param = new SqlParameter("TCKN", tckn);
parameters.Add(param);
DataTable dtSonuc = dbOperations.GetData("MUSTERI_SELECT", parameters);
for (int i = 0; i < dtSonuc.Rows.Count; i++)
{
SosyalOdeme sosyalOdeme = new SosyalOdeme();
sosyalOdeme.OdemeNo = Convert.ToInt32(dtSonuc.Rows[i]["ODEMENO"]);
sosyalOdeme.Tckn = Convert.ToString(dtSonuc.Rows[i]["TCKIMLIKNO"]);
sosyalOdeme.Adi = dtSonuc.Rows[i]["MUSTERIAD"].ToString();
sosyalOdeme.SoyAdi = dtSonuc.Rows[i]["MUSTERISOYAD"].ToString();
sosyalOdeme.OdemeKd = Convert.ToInt32(dtSonuc.Rows[i]["ODEME_KD"]);
sosyalOdeme.OdenecekTtr = Convert.ToDecimal(dtSonuc.Rows[i]["ODENECEK_TTR"]);
if (dtSonuc.Rows[i]["ODEME_TR"] != DBNull.Value)
sosyalOdeme.OdenecekDt = Convert.ToDateTime(dtSonuc.Rows[i]["ODEME_TR"]);
sosyalOdemeleri.Add(sosyalOdeme);
}
return Ok(sosyalOdemeleri);
}
else return Ok("hatalı tckn girdiniz");
}
catch (Exception)
{
throw;
}
}
[HttpPut(Name = "OdemeYapildiSosyalOdeme")]
public ActionResult<bool> Put(string tckn, int odemeNo)
{
try
{
//Yapılacak: Odeme no ve tckn e ait ödemeyi bul
//Ödemenin durum kontrolü yap =0 ise
//eğer kontrolden başarılı geçmez ise false dön işlemi kes
DbOperations dbOperations = new DbOperations();
var parameters = new List<SqlParameter>();
var param1 = new SqlParameter("TCKN", tckn);
parameters.Add(param1);
var param2 = new SqlParameter("ODEMENO", odemeNo);
parameters.Add(param2);
if (odemeKd == 0)
{
dbOperations.ExecuteNonQuery("ODEME_YAP", parameters);
return Ok(true);
}
else return Ok(false);
}
catch (Exception)
{
throw;
}
}
}
}
So that's the whole code for odemeKd.
We have one more big code but there is no definition in the other one.
So i hope you can find the answer of this code.
Thank you so much.
I want to use the Builder pattern and use that by method chaining.
This is my class:
public class SQLGenerator : ISQLGenerator
{
private readonly SQLGeneratorModel generatorModel;
public SQLGenerator()
{
generatorModel = new SQLGeneratorModel();
}
public ISQLGenerator From(string TableName)
{
generatorModel.TabelName = string.Format("FROM {0}", TableName);
return this;
}
public ISQLGenerator Select(List<string> SelectItems)
{
StringBuilder select = new StringBuilder();
var lastItem = SelectItems.Last();
foreach (var item in SelectItems)
{
if (!item.Equals(lastItem))
{
select.Append(item).Append(" , ");
}
else
{
select.Append(item);
}
}
generatorModel.Select =string.Format("SELECT {0}", select.ToString());
return this;
}
This is how this class is used:
SQLGenerator generator = new SQLGenerator();
List<string> select = new List<string>();
select.Add("id");
select.Add("Name");
var str = generator.Select(select).From("AppUsers");
Console.WriteLine(str);
Now I expect a string to be returned like this: SELECT ID , NAME FROM APPUSER but it shows me this result in the console:
SqlPagingGenerator.Pattern.SQLGenerator
How can I show the string result?
The reason for your error is that you are returning an object from the method not a string.
All you have to do is to override the ToString method of your class to return the string you want.
public class SQLGenerator : ISQLGenerator
{
....
public override string ToString()
{
return $"{generatorModel.TableName} {generatorModel.Select}";
}
}
I have a controller that calls an api to get a list of Positions and Employees . First it puts the api results into a model class - IDMSElements (1). Then the controller takes the IDMSElements object and converts it to a PositionSlots object (2). Then the PositionSlots object needs to be updated with additional data from a database (3). So in simplified version of my controller I have:
(1) IDMSElements elements = getslots.CopyDocToElements(doc);
(2) PositionSlots myslots = (PositionSlots)elements;
(3) myslots.UpdateDetails(db);
I am concerned about the myslots.UpdateDetails(db) because additional code in the controller depends on UpdateDetails having been run. I would like the UpdateDetails to be run by default when creating the PositionSlots object. But I think multiple database calls in a constructor probably should not be done. How can I make it so the UpdateDetails is automatically invoked after the PositionSlots object is instantiated?
Thank you very much!
Controller:
[Authorize]
public class PSListController : Controller
{
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private PositionControlContext db = new PositionControlContext();
private GetPositionSlots getslots = new GetPositionSlots();
...
public async Task<ActionResult> ByCostCenter(int costCenter)
{
string ssapiuri = getslots.BuildAPIuri($"/current/?UDAKunit={costCenter.ToString()}");
_logger.Debug($"{ssapiuri.ToString()}");
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
HttpResponseMessage result = await getslots.GetDataFromIDMSapi(ssapiuri);
stopWatch.Stop();
_logger.Debug($"Response received. Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}");
if (result.StatusCode != HttpStatusCode.OK)
{
_logger.Debug("Error retrieving data from API. Milliseconds elapsed: " + stopWatch.Elapsed.TotalMilliseconds.ToString());
throw new HttpException(404, "NotFound");
}
stopWatch.Restart();
XDocument doc = XDocument.Load(result.Content.ReadAsStreamAsync().Result);
stopWatch.Stop();
_logger.Debug($"API result loaded into XDocument. Milliseconds elapsed: {stopWatch.Elapsed.TotalMilliseconds.ToString()}\n");
_logger.Debug(doc.ToString());
IDMSElements elements = getslots.CopyDocToElements(doc);
XMLDocStats docstats = new XMLDocStats(elements);
_logger.Debug(docstats.ToString());
PositionSlots myslots = (PositionSlots)elements;
myslots.UpdateDetails(db);
//because this is dependent upon UpdatePositionSlotId having been run
//need to find a way to force UpdateDetails to run other than calling from Controller??
var mainPositionSlots = myslots.PositionsCurrentAndActive;
var budget = db.Database.SqlQuery<Budget>("GetBudgetForCostCenter #costCenter = {0}", costCenter);
List<Budget> budgetRows = budget.ToList();
JobClassGroups jobClassGroups = new JobClassGroups(mainPositionSlots, budgetRows);
Department dept = db.Departments.AsNoTracking().Where(d => d.CostCenter == costCenter).SingleOrDefault();
var model = new ByCostCenter_vm(dept, myslots, jobClassGroups);
ViewBag.stats = docstats.ToString();
return View("ByCostCenter", model);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
IDMSElements Class:
public class IDMSElements
{
//properties
public ICollection<IDMSElementData> Elements { get; set; }
//constructors
public IDMSElements() { }
public IDMSElements(ICollection<IDMSElementData> elList)
{
Elements = elList;
}
//methods
public static explicit operator PositionSlots(IDMSElements obj)
{
//this is assuming we are looking at a list of elements
//that contains the "current" positions
Dictionary<string, PositionSlotDetail> positionSlots = new Dictionary<string, PositionSlotDetail>();
var sorted = from element in obj.Elements
orderby element.positionNbr
select element;
foreach (IDMSElementData el in sorted)
{
if (!positionSlots.ContainsKey(el.positionNbr))
{
PositionSlotDetail psd = new PositionSlotDetail
{
CostCenter = Int32.Parse(el.UDAKunit),
CostCenter_7Char = el.UDAKunit,
PositionNumber = el.positionNbr,
PositionSlotId = 0,
JobClassId = el.jobClassCode.Replace("-", ""),
JobClassFullDisplayCd = string.Empty,
JobTitle = string.Empty,
SalaryGradeCd = string.Empty,
FTE_percent = el.FTEpercent / 100,
EmployeeId = el.employeeID,
EmployeeName = String.Empty,
PositionEffDate = el.positionEffDate,
PositionEffDateNext = el.positionEffDateNext,
PositionBeginDate = el.positionBeginDate,
PositionEndDate = el.positionEndDate,
DirectLeaderID = string.Empty,
DirectLeaderName = string.Empty,
DirectLeaderNetID = string.Empty,
FLSAstatusCode = el.FLSAstatusCode,
FLSAstatusDesc = el.FLSAstatusDesc,
EmploymentTypeCode = el.employmentTypeCode,
EmploymentTypeDesc = el.employmentTypeDesc,
IsOverloaded = false,
};
positionSlots[el.positionNbr] = psd;
}
Assignment newAssignment = new Assignment
{
PvID = el.employeeID,
AssignBeginDate = el.assignBeginDate,
AssignEndDate = el.assignEndDate,
AssignEffDate = el.assignEffDate,
AssignEffDateNext = el.assignEffDateNext,
};
PositionSlotDetail thePSD = positionSlots[el.positionNbr];
thePSD.Assignments.Add(newAssignment);
if (thePSD.Assignments.Any(assignment => Regex.IsMatch(assignment.PvID, #"^\d+$")))
{
thePSD.Status = "FILLED";
if (thePSD.Assignments.Where(assignment => Regex.IsMatch(assignment.PvID, #"^\d+$")).Count() > 1)
{
thePSD.IsOverloaded = true;
}
}
else
{
thePSD.Status = "VACANT";
}
}
var output = new PositionSlots(positionSlots.Values.ToList());
return output;
}
...
}
PositionSlots class:
public class PositionSlots
{
//Constructor
public PositionSlots(ICollection<PositionSlotDetail> pslist)
{
Positions = pslist;
}
//properites
public ICollection<PositionSlotDetail> Positions { get; }
private bool DetailsUpdated { get; set; } = false;
public IEnumerable<PositionSlotDetail> PositionsCurrentAndActive
{
get
{
return from position in Positions
where position.PositionSlotId > 0 && position.PositionEndDate >= DateTime.Today
select position;
}
}
public IEnumerable<PositionSlotDetail> PositionsNotFoundInPositionControl
{
get
{
return from position in Positions
where position.PositionSlotId == 0
select position;
}
}
public IEnumerable<PositionSlotDetail> PositionsClosed
{
get
{
return from psd in Positions
where psd.PositionEndDate < DateTime.Today
&& psd.PositionSlotId > 0
select psd;
}
}
public decimal ActualFTETotal
{
get
{
return (from position in PositionsCurrentAndActive
from assignment in position.Assignments
where position.Assignments.Count() >= 1 && (!assignment.PvID.Equals("VACANT"))
select position.FTE_percent).Sum();
}
}
public int FilledTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.Status == "FILLED").Count();
}
}
public int VacantTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.Status == "VACANT").Count();
}
}
public int OverloadedTotal
{
get
{
return PositionsCurrentAndActive.Where(x => x.IsOverloaded).Count();
}
}
//methods
public void UpdateDetails(PositionControlContext db)
{
if (!DetailsUpdated)
{
UpdateJobClassificationInfo(db);
UpdateEmployeeName(db);
UpdatePositionSlotId(db); //if not found, PositionSlotId = 0
//UpdateIsBudgeted(db);
UpdateDirectLeader(db);
DetailsUpdated = true;
}
else
{
return;
}
}
private void UpdateJobClassificationInfo(PositionControlContext db)
{
string[] jobClassIds = (from x in Positions select x.JobClassId).Distinct().ToArray();
var JobClassList = (from jc in db.JobClassifications where jobClassIds.Contains(jc.JobClassId) select jc).ToDictionary(jc => jc.JobClassId, jc => jc, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
if (!string.IsNullOrWhiteSpace(psd.JobClassId) && !psd.JobClassId.Equals("MISSING"))
{
JobClassification jobClassification;
if (JobClassList.TryGetValue(psd.JobClassId, out jobClassification))
{
psd.JobClassFullDisplayCd = jobClassification.JobClassFullDisplayCd;
psd.JobTitle = jobClassification.JobTitle;
psd.SalaryGradeCd = jobClassification.SalaryGradeCd;
}
else
{
psd.JobClassFullDisplayCd = ($"{psd.JobClassId} not found in view V_JobClassifications.");
psd.JobTitle = ($"{psd.JobClassId} not found in view V_JobClassifications.");
psd.SalaryGradeCd = "--";
}
}
else
{
psd.JobClassFullDisplayCd = "MISSING";
psd.JobTitle = "MISSING";
}
}
return;
}
private void UpdateEmployeeName(PositionControlContext db)
{
string[] empIdsStr = (from position in Positions
from assignment in position.Assignments
where (!assignment.PvID.Equals("VACANT"))
select assignment.PvID).Distinct().ToArray();
// Positions.SelectMany(x => x.Assignments).SelectMany(x => x.PvID).ToArray();
//string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
//int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);
var EmployeeList = (from emp in db.IdAM_personLU where empIdsStr.Contains(emp.pvID) select emp).ToDictionary(emp => emp.pvID,
emp => emp.EmployeeFullName, StringComparer.OrdinalIgnoreCase);
EmployeeList["VACANT"] = "VACANT";
foreach (PositionSlotDetail psd in Positions)
{
string empName;
if (EmployeeList.TryGetValue(psd.EmployeeId, out empName))
{
psd.EmployeeName = empName;
}
else
{
psd.EmployeeName = ($"{psd.EmployeeId} not found in Employee table.");
}
foreach (Assignment emp in psd.Assignments)
{
string empName2;
if (EmployeeList.TryGetValue(emp.PvID, out empName2))
{
emp.EmpDisplayName = empName2;
}
else
{
emp.EmpDisplayName = ($"{psd.EmployeeId} not found in Employee table.");
}
}
}
return;
}
private void UpdateDirectLeader(PositionControlContext db)
{
string[] empIdsStr = (from x in Positions where (!x.EmployeeId.Contains("VACANT")) select x.EmployeeId).Distinct().ToArray();
//int[] empIdsInt = Array.ConvertAll(empIdsStr, int.Parse);
Dictionary<string, IdAM_arborLU> DirectLeader = new Dictionary<string, IdAM_arborLU>();
var EmployeeDirectLeaderList = (from emp in db.IdAM_arborLU where empIdsStr.Contains(emp.emp_pvID) select emp).ToDictionary(emp => emp.emp_pvID,
emp => emp, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
if (psd.EmployeeId != "VACANT") //will just leave DirectLeaderId and DirectLeaderName as string.Empty
{
IdAM_arborLU supervisor;
if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor))
{
psd.DirectLeaderName = supervisor.sup_name;
psd.DirectLeaderID = supervisor.sup_pvID;
psd.DirectLeaderNetID = supervisor.sup_netID;
}
else
{
psd.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
}
}
foreach (Assignment emp in psd.Assignments)
{
if (psd.EmployeeId != "VACANT")
{
IdAM_arborLU supervisor2;
if (EmployeeDirectLeaderList.TryGetValue(psd.EmployeeId, out supervisor2))
{
emp.DirectLeaderName = supervisor2.sup_name;
emp.DirectLeaderID = supervisor2.sup_pvID;
emp.DirectLeaderNetID = supervisor2.sup_netID;
}
else
{
emp.DirectLeaderName = ($"{psd.EmployeeId} not found in Arbor table.");
emp.DirectLeaderID = "--";
emp.DirectLeaderNetID = "--";
}
}
}
}
return;
}
private void UpdatePositionSlotId(PositionControlContext db)
{
string[] posnumber = (from x in Positions
select x.PositionNumber).ToArray();
var slots = (from ps1 in db.PositionSlots
where posnumber.Contains(ps1.PositionNumber)
select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.PositionSlotId, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
int posSlotId = 0;
if (slots.TryGetValue(psd.PositionNumber, out posSlotId))
{
psd.PositionSlotId = posSlotId;
}
}
return;
}
private void UpdateIsBudgeted(PositionControlContext db)
{
string[] posnumber = (from x in Positions
select x.PositionNumber).ToArray();
var slots = (from ps1 in db.PositionSlots
where posnumber.Contains(ps1.PositionNumber)
select ps1).ToDictionary(ps => ps.PositionNumber.Trim(), ps => ps.IsBudgeted, StringComparer.OrdinalIgnoreCase);
foreach (PositionSlotDetail psd in Positions)
{
bool isbudgeted = false;
if (slots.TryGetValue(psd.PositionNumber, out isbudgeted))
{
psd.IsBudgeted = isbudgeted;
}
}
return;
}
}
you can achieve this by writing a method:
IDMSElement.ToPositionSlot(db)
and then use it as follow:
PositionSlots myslots = elements.Select(x => x.ToPositionSlot(db))
Sorry if the title does not reflect what I actually want.
I'm creating a generic class for selecting, updating, inserting and deleting dates from and to a database.
Basically, I want a function that gives me back an ObservableCollection<"can be anything"> ==> Where anything is a class and not strings. I would like to know if it is possible to do this, if yes, please,help me how I can achieve this.
this is my starting point:
//class a
public static ObservableCollection<ContactPerson> contactPersons = new ObservableCollection<ContactPerson>();
public static ObservableCollection<ContactPerson> getContactPerson()
{
contactPersons = (ObservableCollection<ContactPerson>)DBConnection.GetDataOutDatabase(typeof(ContactPerson), "Contactpersoon");
return contactPersons;
}
//class b
public static Object GetDataOutDatabase(Type myType,String table)
{
ObservableCollection<Object> objecten = new ObservableCollection<Object>();
string sql = "SELECT * FROM " + table;
DbDataReader reader = Database.GetData(sql);
while (reader.Read())
{
objecten.Add(Create(myType, reader));
}
return objecten;
}
private static Object Create(Type myType, IDataRecord record)
{
PropertyInfo[] myPropertyInfo = myType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < myPropertyInfo.Length; i++)
{
PropertyInfo myPropInfo = (PropertyInfo)myPropertyInfo[i];
String name = myPropInfo.Name;
Type type = myPropInfo.PropertyType;
}
return null;
}
And this is what I ultimately want to get. Is this possible?
//ContactPerson cp = new ContactPerson();
//cp.ID = (record["ID"].ToString());
//cp.Name = record["Name"].ToString();
//cp.Company = record["Company"].ToString();
//cp.JobTitle = new ContactPersonTitle()
//{
// Name = record["JobTitle"].ToString(),
//};
//cp.JobRole = new ContactPersonType()
//{
// Name = record["JobRole"].ToString(),
//};
//cp.City = record["City"].ToString();
//cp.Email = record["Email"].ToString();
//cp.Phone = record["Phone"].ToString();
//cp.Cellphone = record["Cellphone"].ToString();
Many thanks!
You can actually do this with reflection in generic methods.
public class DBConnection
{
public static ObservableCollection<T> GetDataOutDatabase<T>(string table)
{
var objecten = new ObservableCollection<T>();
string sql = "SELECT * FROM " + table;
DbDataReader reader = Database.GetData(sql);
while (reader.Read())
{
objecten.Add(Create<T>(reader));
}
return objecten;
}
public static T Create<T>(IDataRecord record)
{
var properties = typeof(T).GetProperties();
var returnVal = Activator.CreateInstance(typeof(T));
properties.ToList().ForEach(item =>
{
try
{
if (item.PropertyType.IsPrimitive)
{
item.SetValue(returnVal, Convert.ChangeType(record[item.Name].ToString(), item.PropertyType),null);
}
else
{
object[] parameters = {record};
var value =
typeof(DBConnection).GetMethod("Create").MakeGenericMethod(item.PropertyType).Invoke(null, parameters);
item.SetValue(returnVal,value,null);
}
}
catch
{
Write("Property Not Found");
}
});
return (T)returnVal;
}
}
The example above does assume that all properties names match the column names you are retrieving from your database communication. For instance in the ContactPersonTitle above rather than Name you would need to have JobTitle as the property name.
Not as you are currently doing it. You should look into the entity framework which allows translation of database tables datacollections.
have a look at:
http://www.codeproject.com/Articles/363040/An-Introduction-to-Entity-Framework-for-Absolute-B
I need to write a script which merges a list with a dictionary to create a third dictionary. I'm pretty new to programming and am struggling with the basics here.
So far I've created the following class which generates a list of dates. I have another class which generates a dictionary and I want to basically create a third dictionary which contains the dates and data which do not exist already in the first list.
Any ideas how I should do this? Thanks.
class StartList: IDisposable
{
private readonly string[] names = new[] { "name1", "name2", "name3"};
private SqlConnection conn;
private Dictionary<string, List<DateTime>> startData = new Dictionary<string, List<DateTime>>();
public StartList()
{
this.conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NameCon"].ConnectionString);
this.conn.Open();
}
private void Dispose()
{
if (this.conn != null)
{
if (this.conn.State != ConnectionState.Closed)
{
try
{
this.conn.Close();
}
catch
{
}
}
this.conn.Dispose();
this.conn = null;
}
}
public void ImportStartData()
{
foreach (string name in this.names)
{
this.startData.Add(name, this.ImportStartData(name));
}
}
public List<DateTime> ImportStartData(string name)
{
List<DateTime> result = new List<DateTime>();
string sqlCommand = string.Format("SELECT * FROM {0}_Index ", name);
using (SqlCommand cmd = new SqlCommand(sqlCommand, this.conn))
{
cmd.CommandType = CommandType.Text;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader.GetDateTime(0));
}
}
}
return result;
}
}
First you need to modify the below code block
From:
public void ImportStartData()
{
foreach (string name in this.names)
{
this.names.Add(name, this.ImportStartData(name));
}
}
To:
public void ImportStartData()
{
foreach (string name in this.names)
{
if(!startData.ContainsKey(name)) //If this check is not done, then Dictionary will throw, duplicate key exception.
{
this.startData.Add(name, this.ImportStartData(name));
}
}
}
Anyway, the better approach would be, if possible first read the name as well as Date from database, possibly into a DataTable and then using LINQ/foreach loop, group the results by name.