c# set DataContext column values without strongly typing it - c#

//Instead of the this
var tableX = db.PRODUCT; //db is the DataContext
//I can do the below (Thanks to http://stackoverflow.com/questions/1919632/get-table-data-from-table-name-in-linq-datacontext
string tablename = "PRODUCT";
var table = (ITable)db.GetType().GetProperty(tablename).GetValue(db, null);
//But instead of this
PRODUCT _Product = new PRODUCT();
_Product.PRD_CODE = "code1";
_Product.PRD_DESC = "description1";
table.InsertOnSubmit(_Product);
db.SubmitChanges();
//How can I do something like this
string tablename = "PRODUCT";
var table = (ITable)db.GetType().GetProperty(tablename).GetValue(db, null);
string lsColumnPrdCode = "PRD_CODE";
string lsColumnPrdDesc = "PRD_DESC";
table _tableInstance = new table();
_tableInstance[lsColumnPrdCode] = "code1";
_tableInstance[lsColumnPrdDesc] = "description1";
_tableInstance.InsertOnSubmit(_tableInstance);
db.SubmitChanges();
So it is possible to set datacontext column values without strongly typing it?

Of cause you can use reflection to do that kind of stuff. Maybe something similar to this code:
Type productType = Type.GetType("PRODUCT");
var product = Activator.CreateInstance(productType);
productType.GetProperty("PRD_CODE").SetValue(product, "code1");
productType.GetProperty("PRD_DESC").SetValue(product, "description1");
Type tableType = table.GetType();
tableType.GetMethod("InsertOnSubmit").Invoke(table, new object[] {product});
But why do you want to do that?

Related

ExecuteNonQuery is not resolving parameters passed to it

I am attempting to add the variable newRetentionLimit to a table in Microsoft SQL Server. I pass the value I want to insert into a parameter and then run ExecuteNonQuery. I get no errors back but the newRetentionLimit isn't placed into the table. I have debugged to make sure that newRetentionLimit isn't null and is an actual integer.
The problem appears to be that ExecuteNonQuery isn't retrieving the parameter value based on the name I put in the script. It appears its just trying to run the script with the parameter name. Anyone have any idea why?
if (request.SystemSettings.Any(s => s.SettingName.Equals("HISTORYRETENTIONDAYS")))
{
var entities = entityRepo.GetList();
var newRetentionLimit = request.SystemSettings.Find(setting => setting.SettingName.Equals("HISTORYRETENTIONDAYS")).SettingValue.ToInt();
var requestContext = new RequestContext();
var sqlParameter = new List<SqlParameter> {
SqlParameterMaker.MakeTypedValueParameter("#retentionValue",newRetentionLimit, SqlDbType.Int)
};
foreach (var entity in entities)
{
var sql = $#"ALTER TABLE [data].[t{entity.Name}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [hist].[t{entity.Name}], HISTORY_RETENTION_PERIOD = #retentionValue DAYS));";
requestContext.DatabaseContext.ExecuteNonQuery(sql, sqlParameter);
}
}
I ended up finding a solution that still allows me to maintain the use of SqlParameter
if (request.SystemSettings.Any(s => s.SettingName.Equals("HISTORYRETENTIONDAYS")))
{
var entities = entityRepo.GetList();
var newRetentionLimit = request.SystemSettings.Find(setting => setting.SettingName.Equals("HISTORYRETENTIONDAYS")).SettingValue.ToInt();
var requestContext = new RequestContext();
foreach (var entity in entities)
{
var sqlParameters = new List<SqlParameter>{
new SqlParameter("#entityName", entity.Name),
new SqlParameter("#retentionPeriod", newRetentionLimit)
};
var sql = "EXEC('ALTER TABLE [data].[t' + #entityName + '] SET (SYSTEM_VERSIONING = ON (HISTORY_RETENTION_PERIOD = ' + #retentionPeriod + ' DAYS))');";
requestContext.DatabaseContext.ExecuteNonQuery(sql, sqlParameters.ToArray());
}
}

How do I add data from a string field to the model as a property?

I am separating a string field I have below by splitting it.
String : D837D323-40A0-1EDD-F365-A55C43725DE0|SPECODE,10A4F529-CDFB-7553-0D05-7C9A36A721F8|SPECODE2,BCAA7E77-DF1D-3135-AD4C-823CEC02ED56|SPECODE3,24CC7FBE-5F43-67FC-7998-73869E2B6D5B|SPECODE4,DF15B062-3072-E3A3-A268-F2DEC8CF947B|SPECODE5,F56355C9-CCF6-095E-F697-DE36BAF464A7|CYPHCODE
Split & UnitOfWork :
using (var dbFactory = new DbFactory()){
var specialCodeList = new List<SpecialCodeModel>();
string[] specialCode = _settings.SpecialCode.Split(',');
for (int i = 0; i < specialCode.Length; i++)
{
int position = specialCode[i].IndexOf('|');
specialCodeList.Add(new SpecialCodeModel
{
EkGuid = specialCode[i].Substring(0, position),
ErpProperty = specialCode[i].Substring(position + 1),
SystemTypeName = "System.String"
});
}
var factory = new DynamicTypeFactory();
var extendedType = factory.CreateNewTypeWithDynamicProperties(typeof(CustomerDto),
specialCodeList);
// Get all read/write properties for the extended Type.
var properties = extendedType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && p.CanWrite);
var connection = dbFactory.GetConnection(_settings);
_settings = GetLogoFirmInfo(parameters, _settings, connection);
string query = SetLogoDbSettings(LogoSqlCommands.CustomerListCountCmd(), parameters, _settings);
int dataCount = connection.QueryFirstOrDefault<int>(query);
query = SetLogoDbSettings(LogoSqlCommands.CustomerListCmd(_settings), parameters, _settings);
var data = connection.Query<CustomerDto>(query);
return QueryResult<IEnumerable<CustomerDto>>.CreateResult(data, dataCount, parameters.PagingLimit, parameters.PagingOffset);
}
Then I assign SpecialCodeModel to this model.
What I want to do is to automatically add the EkGuid fields to the CustomerDto model as a System.String property. Then I add a query using dapper with ErpProperty.The query formed as EKGuid AS ErpProperty should bring me a full CustomerDto.Of course, with the fields, I added specifically.
I tried something, it added to the model, but the dapper did not fill the fields :( I need help with this.
Idea: Construct a SQL command by using a fixed set of aliases that can be mapped by Dapper:
SELECT
[D837D323-40A0-1EDD-F365-A55C43725DE0] AS Column1,
[10A4F529-CDFB-7553-0D05-7C9A36A721F8] AS Column2
...
FROM mytable
Now, you can create a class having a fixed set of properties
public class Data
{
public string Column1 { get; set; }
public string Column2 { get; set; }
...
}
The SQL command can be constructed like this:
var specialCodes = _settings.SpecialCode.Split(',')
.Select(s => {
string[] parts = s.Split('|');
return new SpecialCodeModel {
EkGuid = parts[0],
ErpProperty = parts[1],
SystemTypeName = "System.String"
};
});
var selectList = specialCodes
.Select((s, i) => $"[{s.EkGuid}] AS Column{i + 1}");
string sql = $"SELECT\r\n {String.Join(",\r\n ", selectList)}\r\nFROM myTable";
Console.WriteLine(sql);
With the string from above it creates this output:
SELECT
[D837D323-40A0-1EDD-F365-A55C43725DE0] AS Column1,
[10A4F529-CDFB-7553-0D05-7C9A36A721F8] AS Column2,
[BCAA7E77-DF1D-3135-AD4C-823CEC02ED56] AS Column3,
[24CC7FBE-5F43-67FC-7998-73869E2B6D5B] AS Column4,
[DF15B062-3072-E3A3-A268-F2DEC8CF947B] AS Column5,
[F56355C9-CCF6-095E-F697-DE36BAF464A7] AS Column6
FROM myTable
Make sure to escape the column names the appropriate way for the DB type ([] for SQL-Server, "" for Oracle, etc.).

Bind DropDownList from List<Objects>

I have one list of objects
var listOfUsr = new List<User>();
listOfUsr = GetUserByAgentId("some_id");
if (listOfUsr != null)
{
DropDownList.DataSource = listOfModels;
//DropDownList.DataTextField = "how to set value_from User.Name ?";
//DropDownList.DataValueField = "how to set value_from User.ID ?";
DropDownList.DataBind();
}
How can I set text and value field from object properties?
You just have to set Column Name in DataTextField and DataValueField.
In your case Name and ID are column names for your list object of user.
if (listOfUsr != null)
{
DropDownList.DataSource = listOfModels;
DropDownList.DataTextField = "Name";
DropDownList.DataValueField = "ID";
DropDownList.DataBind();
}
You could try this one:
DropDownList.DataTextField = "Name";
DropDownList.DataValueField = "ID";
I suppose, as it can be concluded from your comments, that an object of type User has two properties called Name and ID and these are the text and value correspondingly that you want to show.
Use a ComboBox and set DropDownStyle =ComboBoxStyle.DropDownList;
Try this code:
var listOfUsr = new List<User>();
listOfUsr = GetUserByAgentId("some_id");
comboBox1.DropDownStyle =ComboBoxStyle.DropDownList;
comboBox1.DataSource=lstOfUsr;
comboBox1.DisplayMember="Description";
You can also drag an object of type BindingSource and use it in this mode:
var listOfUsr = new List<User>();
listOfUsr = GetUserByAgentId("some_id");
bindingSourceListOfObject.DataSource = lstOfUsr;
comboBox1.DropDownStyle =ComboBoxStyle.DropDownList;
comboBox1.DataSource=bindingSourceListOfObject;
comboBox1.DisplayMember="Description";
With BindingSource have many possibilities and flexibility on complex scenario.

How do you return A Table with inserted information in LINQ TO SQL?

I want to return a table which I have edited/added information/inserted data to. Here's my code.
using(DbClassesDataContext myDb = new DbClassesDataContext(dbPath)){
PatientInfo patientInfo = new PatientInfo();
patientInfo.Phy_ID = physcianID;
patientInfo.Pat_First_Name = txtFirstName.Text;
patientInfo.Pat_Middle_Name = txtMiddleName.Text;
patientInfo.Pat_Last_Name = txtLastName.Text;
patientInfo.Pat_Gender = cmbGender.Text;
patientInfo.Pat_Marital_Status = cmbMaritalStatus.Text;
patientInfo.Pat_Date_Of_Birth = dtpDOB.Value;
patientInfo.Pat_Home_Add = txtHomeAdd.Text;
patientInfo.Pat_Home_Num = txtPhone.Text;
patientInfo.Pat_Work_Add = txtWorkAdd.Text;
patientInfo.Pat_Work_Num = txtWorkPhone.Text;
patientInfo.Pat_Prim_Physician = txtPrimPhysician.Text;
patientInfo.Pat_Ref_Physician = txtRefePhysician.Text;
}
Where I want to return patientInfo? what data type is it? how would I create a method which returns it like that?
You can just return the patientInfo object directly, it will be of type PatientInfo (exactly like it appears in your code now).
You are not actually using the DB context that you are generating in your code. I assume you want to insert the new PatientInfo to the DB? Something like:
using(DbClassesDataContext myDb = new DbClassesDataContext(dbPath)){
PatientInfo patientInfo = new PatientInfo();
patientInfo.Phy_ID = physcianID;
patientInfo.Pat_First_Name = txtFirstName.Text;
patientInfo.Pat_Middle_Name = txtMiddleName.Text;
patientInfo.Pat_Last_Name = txtLastName.Text;
patientInfo.Pat_Gender = cmbGender.Text;
patientInfo.Pat_Marital_Status = cmbMaritalStatus.Text;
patientInfo.Pat_Date_Of_Birth = dtpDOB.Value;
patientInfo.Pat_Home_Add = txtHomeAdd.Text;
patientInfo.Pat_Home_Num = txtPhone.Text;
patientInfo.Pat_Work_Add = txtWorkAdd.Text;
patientInfo.Pat_Work_Num = txtWorkPhone.Text;
patientInfo.Pat_Prim_Physician = txtPrimPhysician.Text;
patientInfo.Pat_Ref_Physician = txtRefePhysician.Text;
//store to db
myDb.Patients.AddObject(patientInfo);
myDb.SaveChanges();
return patientInfo;
}
Be careful, the object internally stores a reference to the DataContext you created/updated it with. If you use it together with later updates/inserts that you have the same context for all of them or you will get exceptions.

Updating through LINQ in different DataBase

I have a DB which looks like this:
1st:
CommissionsV2 (Table = Entity_Product_Point)
This is my DBML too which has only one table.
2nd:
WebEnroll (Table = PlanMaster)
This is my another DBML which has one table in it.
Now through LINQ I am adding a row in this which has a query like this:
CommissionsV2DataContext cv = new CommissionsV2DataContext();
Entity_Product_Point ev = new Entity_Product_Point();
ev.Entity_ID = getEntity;
ev.Product_ID = tr.First();
ev.HiCommissionOld = (double)firststYrComp;
ev.LowCommissionOld = (double)recurringComp;
ev.HiCommission = (double)finalFirstYrComp * 100;
ev.LowCommission = (double)finalRecurringComp * 100;
ev.DateCreated = System.DateTime.Now;
cv.Entity_Product_Points.InsertOnSubmit(ev);
cv.SubmitChanges();
Now my update statement is like this:
protected void gvShowComm_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//Getting the Entity_ID from the Session!
int getEntity = Int16.Parse(Session["EntitySelected"].ToString());
//Accessing the variables from the controls!
System.Web.UI.WebControls.TextBox product_ID = gvShowComm.Rows[e.RowIndex].FindControl("ProductName") as System.Web.UI.WebControls.TextBox;
System.Web.UI.WebControls.TextBox planName = gvShowComm.Rows[e.RowIndex].FindControl("PlanName") as System.Web.UI.WebControls.TextBox;
System.Web.UI.WebControls.TextBox hiCommOld = gvShowComm.Rows[e.RowIndex].FindControl("HiComm") as System.Web.UI.WebControls.TextBox;
System.Web.UI.WebControls.TextBox lowCommOld = gvShowComm.Rows[e.RowIndex].FindControl("LowComm") as System.Web.UI.WebControls.TextBox;
//Storing the values into variables!
int product = Int16.Parse(product_ID.Text);
string plan = planName.Text;
int hiOld = Int16.Parse(hiCommOld.Text);
int lowOld = Int16.Parse(lowCommOld.Text);
//Updating the values into the table through LINQ!
dbWebEnrollDataContext dt = new dbWebEnrollDataContext(); //This has PlanName in PlanMaster Table.
CommissionsV2DataContext cv = new CommissionsV2DataContext(); //Entity_Product_Point has all the other columns which needs to be updated!
Entity_Product_Point ev = cv.Entity_Product_Points.Single(c => c.Product_ID == product);
ev.HiCommissionOld = hiOld;
ev.LowCommissionOld = lowOld;
ev.Entity_ID = getEntity;
cv.SubmitChanges();
In order to update, you need to retrieve the entity that needs to be updated.
So in your case it would be:
Entity_Product_Point ev = cv.Entity_Product_Points.Single(c => c.Product_ID == product);
ev.HiCommissionOld = hiOld;
ev.LowCommissionOld = lowOld;
// Retrieve the plan that needs to be updated and set the name
// Submit the changes
cv.SubmitChanges();
// Retrieve the new values and rebind the gridview against the new values

Categories

Resources