I have been trying to convert the code below. I have attempted it and I will post the attempt beneath the code below. I am confused when it comes to
Code That I have to convert:
[TestMethod]
public void SRSTransactiondataCleanTest()
{
using (SqlConnection sqlConn = new
SqlConnection(#"Data Source=localhost;Initial Catalog=CorporateDWTest;Integrated Security=SSPI;"))
{
StringBuilder str = new StringBuilder();
str.Append(#"SELECT * FROM [dbo].[SRS_Ticket_Transaction_Stage_Cleaned]");
sqlConn.Open();
SqlDataAdapter da = new SqlDataAdapter(str.ToString(), sqlConn);
DataTable dResults = new DataTable();
DataTable dAudit = new DataTable();
da.Fill(dResults);
da.SelectCommand.CommandText = #"SELECT [Table_Name],[Package_Name],[Execution_Start_Time],[Execution_End_Time],[Processing_Successful], Audit_Key," +
#"[Table_Initial_Row_Count],[Table_Final_Row_Count] FROM [SRS_Dim_Audit] WHERE Package_Name LIKE 'SAPSRSDataToStageClean'";
da.Fill(dAudit);
var r = dAudit.Rows[0][2].ToString();
Assert.AreEqual(1, dAudit.Rows.Count);
Assert.AreEqual("SRS_Ticket_Transaction_Stage_Cleaned", dAudit.Rows[0][0].ToString());
Assert.AreEqual("SAPSRSDataToStageClean", dAudit.Rows[0][1].ToString());
Assert.AreEqual(bool.TrueString, dAudit.Rows[0][4].ToString());
Assert.IsTrue(int.Parse(dAudit.Rows[0][7].ToString()) > 10);
Assert.IsTrue(dResults.Rows.Count > 50);
Assert.AreEqual(int.Parse(dAudit.Rows[0][7].ToString()), dResults.Rows.Count);
Assert.AreEqual(int.Parse(dAudit.Rows[0][5].ToString()), int.Parse(dResults.Rows[0][2].ToString()))
sqlConn.Close();
}
}
What I have so far:
[TestMethod]
public void SRSTransactiondataCleanTest()
{
using (var context = new CorporateDWTestEntities4())
{
var stageCleaned = context.SRS_Ticket_Transaction_Stage_Cleaned;
var auditRecords = context.SRS_Dim_Audit.Where(s => s.Package_Name == "SAPSRSDataToStageClean");
var auditRecord = auditRecords.FirstOrDefault();
Assert.AreEqual(1, stageCleaned.Count());
Assert.AreEqual(auditRecord.Table_Final_Row_Count, stageCleaned.Count());
Assert.AreEqual(52, auditRecords.Count());
Assert.AreEqual("SRS_Ticket_Transaction_Stage_Cleaned", auditRecord.Table_Name);
Assert.AreEqual("SAPSRSDataToStageClean", auditRecord.Package_Name);
Assert.AreEqual(true, auditRecord.Processing_Successful);
Assert.IsTrue(auditRecord.Table_Final_Row_Count > 10);
}
}
I am fairly new at this code conversion stuff.. Am I on the right track? When I run this I recieve a message that states:
"Assert.AreEqual failed. Expected <1>. Actual <9461>."
When I change it to 9461, the entire test passes. Why is that? Am I using the wrong variable? I would just like to know if the code that I wrote is actually mirroring the code that I was to convert. I know with programming syntax must be meticulous. I was wondering if someone out there could review this and modify IF necessary.
Ps. the line:
Assert.AreEqual(int.Parse(dAudit.Rows[0][5].ToString()), int.Parse(dResults.Rows[0][2].ToString()));
confused the hell out of me, What is that even asking of me?
Your first test should be
Assert.AreEqual(1, auditRecords.Count());
rather than
Assert.AreEqual(1, stageCleaned.Count());
You also have a test
Assert.AreEqual(52, auditRecords.Count());
I can't see where you get 52 free. If this is supposed to be the equivalent of
Assert.IsTrue(dResults.Rows.Count > 50);
then it should be
Assert.IsTrue(stageCleaned.Count() > 50);
Not sure why you are confused by the line
Assert.AreEqual(int.Parse(dAudit.Rows[0][5].ToString()), int.Parse(dResults.Rows[0][2].ToString()));
You must be very close as you have already worked out what all the other dAudit.Rows[0][...] values are, so presumably you know that int.Parse(dAudit.Rows[0][5].ToString()) represents auditRecord.Audit_Key (assuming this is defined as an int). Similarly dResults.Rows[0][2] will be the the third column of the first row from the SRS_Ticket_Transaction_Stage_Cleaned table.
So presumably this represents something like
var firstStageRecord = stageCleaned.First();
Assert.IsTrue(auditRecord.Audit_Key , firstStageRecord.xxx);
where xxx is the name of the third column.
There are a few other issues to point out.
If you have several calls to stageCleaned.Count(), it will issue a sql command each time is is called.
The original code was hard-coding the sqlConnection, whereas your new code is either using the default or picking up a connection from a configuration file, so you need to check to ensure you are talking to the correct database.
Related
I have created a custom class list which is filled from the result of a query. Specifically, me query returns (int, timestamp) 2 columns -> 2 values.
public class SucessfulCompletion
{
public int Result;
public string Timestampvalue;
public SucessfulCompletion(int result, string timestamp) => (Result, Timestampvalue) = (result, timestamp);
}
public List<SucessfulCompletion> SuccessfulCalculationsTimestamp(string connectionstring)
{
List<SucessfulCompletion> QueryListResult = new List<SucessfulCompletion>();
using (SqlConnection sqlConnection = new SqlConnection(connectionstring))
{
var query_table_timestamp = (
#"SELECT CASE
WHEN t.STATUS = 'SUCCESS' AND t.STATUS_DESCRIPTION = 'ALL QUERIES COMPLETED SUCCESSFULLY' THEN 1
ELSE 0
END SuccessfulCompletion, t.TIMESTAMP
FROM (SELECT TOP (1) l.TIMESTAMP, l.STATUS, l.STATUS_DESCRIPTION
FROM LOG_DETAILS l
ORDER BY 1 DESC) t");
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand(query_table_timestamp, sqlConnection))
{
using (SqlDataReader reader = sqlCommand.ExecuteReader())
{
while (reader.Read())
{
QueryListResult.AddRange(new List<SucessfulCompletion>
{
new SucessfulCompletion(reader.GetInt32(0), reader.GetDateTime(1).ToString())
});
}
reader.Close();
}
sqlCommand.Cancel();
}
}
return QueryListResult;
}
The code to create the custom class list was taken from this SO question
So the QueryListResult would be like [1, "2020-10-04 HH:MM:SS"]
Now I want to make an if statement to check if the first index of the QueryListResult is ether 0 or 1.
List<SucessfulCompletion> reportsucessfulcompletion = new List<SucessfulCompletion>();
reportsucessfulcompletion = SuccessfulCalculationsTimestamp(SQLServerConnectionDetails());
if (reportsucessfulcompletion[0]=1) //my problem is here
{
//Enable is only if successful
PreviewCalculationsButton.IsEnabled = true;
PreviewReportButton.IsEnabled = true;
//add textbox of success
SQLSuccessfulTextCalculations.Text = String.Format("Completed On: {0}", reportsucessfulcompletion[1]);
}
else
{
//add textbox of fail
SQLFailedTextCalculations.Text = String.Format("Failed On: {0}", reportsucessfulcompletion[1]);
}
In the if statement I get an error
Cannot implicitly convert type 'int' to 'TestEnvironment.MainWindow.SucessfulCompletion'
I know it may be a silly question for someone experienced with C# but I am a newbie, so I would appreciate your help. Please inform me in the comments if the theme of the question is a duplicate one I will close the question.
You're comparing an jnstance of your class to a number.
These are different things.
And one equal sign sets rather than compares
Try
If ( reportsucessfulcompletion[0].Result == 1)
You should make these properties rather than variables.
I also recommend Dapper as a "micro" orm very close to the ado metal, but which saves a fair bit of coding whilst implementing best practice for you.
My team have read-access to a database maintained by a different team. We have a number of scripts that only we run, and so they've never been added as sprocs to the database (nor do we want them to be).
In Entity Framework 6, is it possible to include a file in my model which contains a stored procedure, so that we can leverage the code generation in EF?
We'd much rather have our code look like:
using (var db = new DatabaseEntities())
{
var properlyTypedResult = db.GetEntriesThatStartWith(firstName);
}
than:
using (var db = new DatabaseEntities())
{
var rawResult = db.Database.ExecuteSqlCommand("SELECT * FROM dbo.Person WHERE FirstName LIKE '#p0%'", firstName);
var properlyTypedResult = CastAppropriately(rawResult);
}
The functionality appears to be missing, but I thought I'd check regardless, I'd expect it to be in the designer view,
right-click, Add New -> Function Import...
... but this only allows adding sprocs to the model that are already in the database.
I think you're forgetting about LINQ - the second example would be something like...
List<People> people = (List<People>)db.Person.Where(f => f.FirstName.StartsWith(firstname)).ToList();
This should be close to what you're looking for. Linq is your friend.
I couldn't find exactly what I was after. I decided to simply write my own code generation, and leverage as much of Entity Framework as I could.
With query string in hand, execute against the database appropriately, using a SqlDataAdapter, with a DataTable
e.g.,
using (var context = new DbContext())
{
var dataTable = new DataTable();
var connection = (SqlConnection)context.Database.Connection;
if (connection != null && connection.State == ConnectionState.Closed)
connection.Open();
using (var adapter = new SqlDataAdapter(queryString, connection))
adapter.Fill(dataTable);
}
The DataTable contains the resulting column names along with all their types, now all we have to do is generate the code for the object.
i.e.,
var objectBuilder = new StringBuilder();
objectBuilder.AppendLine("public class QueryResult");
objectBuilder.AppendLine("{");
foreach (DataColumn column in dataTable.Columns)
{
objectBuilder.AppendLine(String.Format("public {0} {1} { get; set; }", column.DataType.Name, column.ColumnName));
}
objectBuilder.AppendLine("}");
Finally, create an extension method on the context object:
i.e.,
private static string GetQueryString(string firstName)
{
return String.Format($"SELECT * FROM dbo.Person WHERE FirstName LIKE '{firstName}%'", firstName);
}
public static partial class DbContextExtensions
{
public static List<QueryResult> GetEntriesThatStartWith(this DbContext context, string firstName)
{
return context.Database.SqlQuery<QueryResult>(GetQueryString(firstName)).ToList();
}
}
Now, we can use this as a regular sproc call:
using (var db = new DbContext())
{
var properlyTypedResult = db.GetEntriesThatStartWith(firstName);
}
I'm new to C# and my current code seems a bit of a hack- how can I keep combining referenced datatables more efficiently (less lines of code), or at least more readable?
(I have no say in the framework, BTW, I'm playing it as it lies ;))
I lose the last datatable once I reference it again
I can't import rows into a datatable that doesn't share the same schema.
This code address both issues, but man, it seems fugly.
DataTable dt_ref = new DataTable();
DataTable dt_final = new DataTable();
bool datatable_is_cloned;
String[] customer_ids = {"cust_a", "cust_b", "cust_c"}
foreach(String id in customer_ids)
{
if(!obj_cust.Select_by_customer_id(id, ref dt_ref, ref error_msg))
{
//do error handling
}
if(!datatable_is_cloned)
{
dt_final = dt_ref.Clone();
datatable_is_cloned = true;
}
foreach(DataRow r in dt_ref.Rows)
dt_final.ImportRow(r);
}
Edited for clarity.
Problem is is every time I loop and hit the database with another customer id, my dt_ref loses all of its previous results and gains merely the new ones (yes, this is expected behavior).
I want to keep a running total of all the results from select method.
I'm currently learning Linq to Sql and Im very surprised by the performance of selecting data. I'm retreving joined data from few tables. I select about 40k of rows. Mapping this data to objects using ADO times about 35s, using NHbiernate times about 130s and what is suspicious using Linq To Sql only 3,5s. Additionally I would like to write that I'm using immediately loading which looks like:
THESIS th = new THESIS(connectionString);
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<NumericFormula>(x => x.RPN);
dlo.LoadWith<RPN>(x => x.RPNDetails);
dlo.LoadWith<RPNDetail>(x => x.Parameter);
th.LoadOptions = dlo;
th.Log = Console.Out;
Looking to the logs when I'm iterating I can't see that Linq To Sql generate some additional queries to database.
I'm very surprised by huge differences in performance and I wonder that maybe I don't understand something.
Could someone explain me why it works so fast?
To measure time I'm using Stopwatch class.
ADO.NET Code:
public static List<NumericFormulaDO> SelectAllNumericFormulas()
{
var nFormulas = new List<NumericFormulaDO>();
string queryString = #"
SELECT *
FROM NumericFormula nf
Left Join Unit u on u.Unit_Id = nf.Unit_Id
Left Join UnitType ut on ut.UnitType_Id = u.UnitType_Id
Join RPN r on r.RPN_Id = nf.RPN_Id
Join RPNDetails rd on rd.RPN_Id = r.RPN_Id
Join Parameter par on par.Parameter_Id = rd.Parameter_Id where nf.NumericFormula_Id<=10000";
using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(queryString, connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var det = new RPNDetailsDO();
det.RPNDetails_Id = Int32.Parse(reader["RPNDetails_Id"].ToString());
det.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString());
det.Identifier = reader["Identifier"].ToString();
det.Parameter.Architecture = reader["Architecture"].ToString();
det.Parameter.Code = reader["Code"].ToString();
det.Parameter.Description = reader["Description"].ToString();
det.Parameter.Parameter_Id = Int32.Parse(reader["Parameter_Id"].ToString());
det.Parameter.ParameterType = reader["ParameterType"].ToString();
det.Parameter.QualityDeviationLevel = reader["QualityDeviationLevel"].ToString();
if (nFormulas.Count > 0)
{
if (nFormulas.Any(x => x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString())))
{
nFormulas.First(x=>x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString())).RPN.RPNDetails.Add(det);
}
else
{
NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det);
nFormulas.Add(nFormula);
//System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString());
}
}
else
{
NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det);
nFormulas.Add(nFormula);
//System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString());
}
}
}
}
return nFormulas;
}
private static NumericFormulaDO CreatingNumericFormulaDO(SqlDataReader reader, RPNDetailsDO det)
{
var nFormula = new NumericFormulaDO();
nFormula.CalculateDuringLoad = Boolean.Parse(reader["CalculateDuringLoad"].ToString());
nFormula.NumericFormula_Id = Int32.Parse(reader["NumericFormula_Id"].ToString());
nFormula.RPN.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString());
nFormula.RPN.Formula = reader["Formula"].ToString();
nFormula.Unit.Name = reader["Name"].ToString();
if (reader["Unit_Id"] != DBNull.Value)
{
nFormula.Unit.Unit_Id = Int32.Parse(reader["Unit_Id"].ToString());
nFormula.Unit.UnitType.Type = reader["Type"].ToString();
nFormula.Unit.UnitType.UnitType_Id = Int32.Parse(reader["UnitType_Id"].ToString());
}
nFormula.RPN.RPNDetails.Add(det);
return nFormula;
}
LINQ to SQL Code:
THESIS th = new THESIS(connectionString);
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<NumericFormula>(x => x.RPN);
dlo.LoadWith<RPN>(x => x.RPNDetails);
dlo.LoadWith<RPNDetail>(x => x.Parameter);
th.LoadOptions = dlo;
th.Log = Console.Out;
var nFormulas =
th.NumericFormulas.ToList<NumericFormula>();
NHibernate Code:
IQueryable<NumericFormulaDO> nFormulas =
session.Query<NumericFormulaDO>()
.Where(x=>x.NumericFormula_Id <=10000);
List<NumericFormulaDO> nForList =
new List<NumericFormulaDO>();
nForList = nFormulas.ToList<NumericFormulaDO>();
Related to your comments you can see that in ADO I'm using SqlReader and in LINQ I try to use immediate execution.
Of course it is possible that my mapping "algorithm" in ADO part it's not very good but NHibernate is much more slow than ADO (4x slower) so I wonder if for sure is everything alright in LINQ to SQL part because I think in NHibernate is everything good and after all is much more slow than little confusing ADO part.
Thank you guys for responses.
LINQ-to-SQL consumes ADO.NET and has additional overheads, so no: it shouldn't be faster unless it isn't doing the same work. There was mention of access via ordinals vs names, but frankly that affects micro-seconds, not seconds. It won't explain an order of magnitude change.
The only way to answer this is to trace what LINQ-to-SQL is doing. Fortunately this is simple - you can just do:
dbContext.Log = Console.Out;
which will write the TSQL is executes to the console. There are two options then:
you discover the TSQL isn't doing the same thing (maybe it isn't eager-loading)
you discover the TSQL is valid (=doing the same), but has a better plan - in which case... "borrow" it :p
Once you have the TSQL to compare, test that side-by-side, so you are testing the same work. If you want the convenience without the overheads, I'd look at "dapper" - takes away the boring grunt-work of mapping readers to objects, but very optimised.
Rewritten ADO.NET code based on above remarks, this should be a lot faster. You could still improve by using the ordinal value instead of the column names and by reading the fields in exactly the same order as in the query, but those are micro optimizations.
I've also removed a couple of duplications. You might also want to check how to improve the performance of typecasting and conversions, as the Parse(ToString) route is very inefficient and can cause very strange issues when running with systems running in different languages. There's also a chance of dataloss when doing these conversions when decimal, float or doubles are involved, as not all of their values can be translated to strings correctly (or can't roundtrip back).
public static List<NumericFormulaDO> SelectAllNumericFormulas()
{
var nFormulas = new Dictionary<int, NumericFormulaDO>();
string queryString = #"
SELECT *
FROM NumericFormula nf
Left Join Unit u on u.Unit_Id = nf.Unit_Id
Left Join UnitType ut on ut.UnitType_Id = u.UnitType_Id
Join RPN r on r.RPN_Id = nf.RPN_Id
Join RPNDetails rd on rd.RPN_Id = r.RPN_Id
Join Parameter par on par.Parameter_Id = rd.Parameter_Id where nf.NumericFormula_Id<=10000";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = new SqlCommand(queryString, connection));
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var det = new RPNDetailsDO();
det.RPNDetails_Id = (int) reader.GetValue("RPNDetails_Id");
det.RPN_Id = (int) reader.GetValue("RPN_Id");
det.Identifier = (string) reader.GetValue("Identifier");
det.Parameter.Architecture = (string)reader.GetValue("Architecture");
det.Parameter.Code = (string)reader.GetValue("Code");
det.Parameter.Description = (string)reader.GetValue("Description");
det.Parameter.Parameter_Id = (int) reader.GetValue("Parameter_Id");
det.Parameter.ParameterType = (string)reader.GetValue("ParameterType");
det.Parameter.QualityDeviationLevel = (string)reader.GetValue("QualityDeviationLevel");
NumericFormulaDO parent = null;
if (!nFormulas.TryGetValue((int)reader.GetValue("RPN_Id"), out parent)
{
parent = CreatingNumericFormulaDO(reader, det);
nFormulas.Add(parent.RPN.RPNID, parent);
}
else
{
parent.RPN.RPNDetails.Add(det);
}
}
}
}
return nFormulas.Values.ToList();
}
I have a winform app that fills a lot of its dropdomn fields fram a maintenance table at runtime. Each Form has a Private void FillMaintFields()
I have run into a strange error where setting the column visibility on 1 form works but on another gives me an index out of range error!
Here is the abriged method on the offending form -->
private void FillMaintFields()
{
var myMCPTableMaint = new TableMaint();
// Index 27 is Diabetic Teaching Topics
var myDataSet = myMCPTableMaint.GetMaintItem(27);
var myDataTable = myDataSet.Tables[0];
// Diabetic TeachingTopics dropdown
chkcboDiabeticTeachingTopics.Properties.DataSource = myDataTable;
chkcboDiabeticTeachingTopics.Properties.DisplayMember = "ItemDescription";
chkcboDiabeticTeachingTopics.Properties.ValueMember = "ItemID";
// Index 26 is Diabetic Teaching
myDataSet = myMCPTableMaint.GetMaintItem(26);
myDataTable = myDataSet.Tables[0];
lkuDiabeticTeaching.Properties.DataSource = myDataTable;
lkuDiabeticTeaching.Properties.PopulateColumns();
lkuDiabeticTeaching.Properties.DisplayMember = "ItemDescription";
lkuDiabeticTeaching.Properties.ValueMember = "ItemID";
lkuDiabeticTeaching.Properties.Columns[0].Visible = false;
lkuDiabeticTeaching.Properties.Columns[1].Visible = false;
lkuDiabeticTeaching.Properties.Columns[3].Visible = false;
lkuDiabeticTeaching.Properties.Columns[4].Visible = false;
}
Now here is the working function on a sister form -->
private void FillMaintFields()
{
var myMCPTableMaint = new TableMaint();
// Index 4 is Minimum Contact Schedule
var myDataSet = myMCPTableMaint.GetMaintItem(4);
var myDataTable = myDataSet.Tables[0];
lkuMinContactSchedule.Properties.DataSource = myDataTable;
lkuMinContactSchedule.Properties.PopulateColumns();
lkuMinContactSchedule.Properties.DisplayMember = "ItemDescription";
lkuMinContactSchedule.Properties.ValueMember = "ItemID";
lkuMinContactSchedule.Properties.Columns[0].Visible = false;
lkuMinContactSchedule.Properties.Columns[1].Visible = false;
lkuMinContactSchedule.Properties.Columns[3].Visible = false;
lkuMinContactSchedule.Properties.Columns[4].Visible = false;
// Index 5 is Release of Information Updated Annually
myDataSet = myMCPTableMaint.GetMaintItem(5);
myDataTable = myDataSet.Tables[0];
lkuReleaseInfoUpdateAnnually.Properties.DataSource = myDataTable;
lkuReleaseInfoUpdateAnnually.Properties.PopulateColumns();
lkuReleaseInfoUpdateAnnually.Properties.DisplayMember = "ItemDescription";
lkuReleaseInfoUpdateAnnually.Properties.ValueMember = "ItemID";
lkuReleaseInfoUpdateAnnually.Properties.Columns[0].Visible = false;
lkuReleaseInfoUpdateAnnually.Properties.Columns[1].Visible = false;
lkuReleaseInfoUpdateAnnually.Properties.Columns[3].Visible = false;
lkuReleaseInfoUpdateAnnually.Properties.Columns[4].Visible = false;}
They are all using the same method in the DAL and accessing the EXACT same table which has a structure of -->
|ItemID | CategoryID | ItemDescription | OrderID | Active|
I am at a loss here as to why it would work in 1 spot and not another. If I comment out the Columns[] portion in the offending Form it returns the correct data with NO errors but, of course ALL columns visible.
Ideas? Thanks!
EDIT 1
Based on some comments and concerns:
The error appears on the first line that tries to access the Columns[]. Wherever and whatever column that may be on the offending Form.
If I debug and look at myDataTable it shows the correct columnms and correct data.
Is the error happening on the "lkuReleaseInfoUpdateAnnually" or the "lkuMinContactSchedule"? Which control is that exactly? It seems the error is on the control side of things, seems like your control in the second form doesn't have all the columns you're expecting it to have.
EDIT: You seem to be confusing the Columns in the dataTable with the columns on your control(s). I'm not sure which control you're using, but doing:
lkuReleaseInfoUpdateAnnually.Properties.Columns[0]
does NOT mean you're indexing into the DataTable. You're indexing into the columns of your control, which may or may not be there.
Create a minimal code that still reproduces a problem. Debug that code; or, if that doesn't help, post it here. The above code doesn't really tell us anything: it's too large, too specific to your problem. We don't know how your data looks, we've got to take your word for the table structure – although C# seems to disagree.
All in all, any help anyone could offer is just fuzzy guesswork.
I have some ideas on how to better specify bugs and their origin. Something you should do, is to watch "lkuDiabeticTeaching.Properties.Columns.Count" value, if, it's less than 1 means, you do not have any columns, and probably because no population occurred.
The only thing I can see is that the first set of code is missing a call to PopulateForms() (it is included in the second set). Could that be it?
Well, I figured it out. Kinda. For some reason I need to call lkuDiabeticTeaching.Properties.ForceInitialize(); after setting the data source on the offending form.
I can only guess that because I have nested forms that somehow this was trying to fire before the control was initialized.
It now looks like this -->
// Index 26 is Diabetic Teaching
harDataSet = myHARTableMaint.GetMaintItem(26);
harDataTable = harDataSet.Tables[0];
lkuDiabeticTeaching.Properties.DataSource = harDataTable;
lkuDiabeticTeaching.Properties.ForceInitialize();
lkuDiabeticTeaching.Properties.PopulateColumns();
lkuDiabeticTeaching.Properties.DisplayMember = "ItemDescription";
lkuDiabeticTeaching.Properties.ValueMember = "ItemID";
if(lkuDiabeticTeaching.Properties.Columns.Count > 0)
{
lkuDiabeticTeaching.Properties.Columns[0].Visible = false;
lkuDiabeticTeaching.Properties.Columns[1].Visible = false;
lkuDiabeticTeaching.Properties.Columns[3].Visible = false;
lkuDiabeticTeaching.Properties.Columns[4].Visible = false;
}
Thanks to all who gave of there time.