Dynamic Array to MS SQL Database - c#

private void getRRvalue(string DELRRNO)
{
try {
DBSFCDataContext SFC = new DBSFCDataContext();
var query = (from i in SFC.POP10500s where i.POPRCTNM == DELRRNO select new { PONO = i.PONUMBER, DATEREC = i.DATERECD, VENDID = i.VENDORID, ITEMCODE = i.ITEMNMBR, QTYBAGS = i.QTYBAGS, QTYSHIP = i.QTYSHPPD, DEPT = i.TRXLOCTN });
foreach (var r in query)
{
string[] row = {
DELRRNO,
r.PONO,
Convert.ToDateTime(r.DATEREC).ToString(),
r.VENDID,
r.ITEMCODE,
r.QTYBAGS.ToString(),
r.QTYSHIP.ToString(),
r.DEPT
};
//glbVariables.getRRNO = ;
//glbVariables.getPONO = ;
//glbVariables.getRRdateRec = ;
//glbVariables.getVendID = ;
//glbVariables.getItemNO = ;
//glbVariables.getQtyBags = ;
//glbVariables.getQtyShipped = ;
//glbVariables.getLocnCode = ;
}
SFC.Connection.Close();
}
catch (Exception ex)
{ MessageBox.Show(ex.Message.ToString()); }
}
I'm new to C#.NET and I was just thinking if I could use a dynamic array like for this code above do I need to declare a global array like this --> "public static string[] row;" so I can use this array string in another form by calling it with the data that I have stored from this function, could this happen in c#?
I need help here please anyone that is good at arrays in c#...

To get you desired results, you will have to do little more work. I explain your solution using List.
First create a class for your one query result:
public class OneRowData
{
public string DELRRNO;
public string PONO;
public string DATEREC;
public string VENDID;
public string ITEMCODE;
public string QTYBAGS;
public string QTYSHIP;
public string DEPT;
}
In your given code, create a List of OneRowData type and make it public static to access it from outside the class as well:
public static List<OneRowData> QueryResults = new List<OneRowData>();
Now in your foreach loop, create an object of OneRowData, assing values to it and add it to the List:
foreach (var r in query)
{
OneRowData Obj = new OneRowData();
//assing values to them
Obj.DATEREC = Convert.ToDateTime(r.DATEREC).ToString();
Obj.DELRRNO = DELRRNO;
Obj.DEPT = r.DEPT;
Obj.ITEMCODE = r.ITEMCODE;
Obj.PONO = r.PONO;
Obj.QTYBAGS = r.QTYBAGS.ToString();
Obj.QTYSHIP = r.QTYSHIP.ToString();
Obj.VENDID = r.VENDID;
//then add the object to your list
QueryResults.Add(Obj);
}
Now you can simply call your List any where and fetch your data like this:
foreach (OneRowData Row in QueryResults)
{
//Row.DATEREC
//Row.DELRRNO
//call them like this and use as you need
}

Related

export file with asp.net

This project is an ASP.Net Api project with Angular. What I'm trying to do is export data from a database table and into an excel file. So far, I've managed to export all the table data into an excel file, but struggle to select 2 or 3 fields in the table to export.
[HttpGet("download")]
public IActionResult DownloadExcel(string field)
{
string dbFileName = "DbTableName.xlsx";
FileInfo file = new FileInfo(dbFileName);
byte[] fileContents;
var stream = new MemoryStream();
using (ExcelPackage package = new ExcelPackage(file))
{
IList<UserTable> userList = _context.UserTable.ToList();
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("DbTableName");
int totalUserRows = userList.Count();
}
return File(fileContents, fileType, dbFileName);
}
There's no need to write so many if ... else if ... else if ... else if ... to get the related field names.
A nicer way is to
Use a field list (IList<string>)as a parameter.
And then generate a required field list by intersect.
Finally, we could use reflection to retrieve all the related values.
Implementation
public IActionResult DownloadExcel(IList<string> fields)
{
// get the required field list
var userType = typeof(UserTable);
fields = userType.GetProperties().Select(p => p.Name).Intersect(fields).ToList();
if(fields.Count == 0){ return BadRequest(); }
using (ExcelPackage package = new ExcelPackage())
{
IList<UserTable> userList = _context.UserTable.ToList();
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("DbTableName");
// generate header line
for(var i= 0; i< fields.Count; i++ ){
var fieldName = fields[i];
var pi= userType.GetProperty(fieldName);
var displayName = pi.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
worksheet.Cells[1,i+1].Value = string.IsNullOrEmpty(displayName ) ? fieldName : displayName ;
}
// generate row lines
int totalUserRows = userList.Count();
for(var r=0; r< userList.Count(); r++){
var row = userList[r];
for(var c=0 ; c< fields.Count;c++){
var fieldName = fields[c];
var pi = userType.GetProperty(fieldName);
// because the first row is header
worksheet.Cells[r+2, c+1].Value = pi.GetValue(row);
}
}
var stream = new MemoryStream(package.GetAsByteArray());
return new FileStreamResult(stream,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
You could configure the display name using the DsiplayNameAttribute:
public class UserTable
{
public int Id{get;set;}
[DisplayName("First Name")]
public string fName { get; set; }
[DisplayName("Last Name")]
public string lName { get; set; }
[DisplayName("Gender")]
public string gender { get; set; }
}
It's possible to add any properties as you like without hard-coding in your DownloadExcel method.
Demo :
passing a field list fields[0]=fName&fields[1]=lName&fields[2]=Non-Exist will generate an excel as below:
[Update]
To export all the fields, we could assume the client will not pass a fields parameter. That means when the fields is null or if the fields.Count==0, we'll export all the fields:
[HttpGet("download")]
public IActionResult DownloadExcel(IList<string> fields)
{
// get the required field list
var userType = typeof(UserTable);
var pis= userType.GetProperties().Select(p => p.Name);
if(fields?.Count >0){
fields = pis.Intersect(fields).ToList();
} else{
fields = pis.ToList();
}
using (ExcelPackage package = new ExcelPackage()){
....
}
}
if you want to use the datatable then we can define which you need to select from the datatable in this way
string[] selectedColumns = new[] { "Column1","Column2"};
DataTable dt= new DataView(fromDataTable).ToTable(false, selectedColumns);
or else if you wanna you list then you can use linq for selection of particular columns
var xyz = from a in prod.Categories
where a.CatName.EndsWith("A")
select new { CatName=a.CatName, CatID=a.CatID, CatQty = a.CatQty};

How can I return result of string Kusto Query from c#

var kusto = string.Format("let MyData = CompanyMydata" +
" | where ID == 'Z123' | top 1 by dateTimeUtc desc");
var reader = client.ExecuteQuery(kusto);
while (reader.Read())
{
//how can i return coming result as list of string or json string?
}
In while loop I can able to return single column value one by one by using
string state = reader.GetString(1); but i want to return complete result instead of one by one column value.
so that i can do JsonConvert.DeserializeObject<T>(resultString); to specific class.
assuming you're using the client libraries mentioned here, you should be able to do something like the following:
static void Main(string[] args)
{
var kcsb = new KustoConnectionStringBuilder("https://help.kusto.windows.net").WithAadUserPromptAuthentication();
var databaseName = "Samples";
using (var queryProvider = KustoClientFactory.CreateCslQueryProvider(kcsb))
{
var clientRequestProperties = new ClientRequestProperties() { ClientRequestId = "Sample;" + Guid.NewGuid() };
var query = "StormEvents | summarize count(), max(EndTime) by State";
var result = queryProvider.ExecuteQuery<MyType>( // focus on this part
databaseName,
query,
clientRequestProperties)
.ToList();
foreach (var row in result)
{
Console.WriteLine($"State = {row.State}, Count = {row.Count}, MaxEndTime = {row.MaxEndTime}");
}
}
}
class MyType
{
public string State;
public long Count;
public DateTime MaxEndTime;
}

How to load multiple lists in a datagridview

I currently work on a Windows Forms application and I have 3 lists of data and I want to add every list to a column of a datagrid. Is there a way how I can do this.
XDocument doc = XDocument.Load(Globals.pathNotifFile);
var dates = doc.Descendants("Date");
var hours = doc.Descendants("Time");
var message = doc.Descendants("Message");
var hoursCollection = new List<String>();
var dateCollection = new List<String>();
var messageCollection = new List<String>();
foreach (var date in dates)
{
dateCollection.Add(date.Value);
}
foreach (var hour in hours)
{
hoursCollection.Add(hour.Value);
}
foreach (var messages in message)
{
messageCollection.Add(messages.Value);
}
return Tuple.Create(hoursCollection,dateCollection, messageCollection);
}
The easiest way to accomplish this task is to build one object which contains your three datapoints. For example:
public class MyGridDateTime
{
public string Hour{get;set;}
public string Date{get;set;}
public string Message{get;set;}
}
public void InitalizeGrid()
{
List<MyGridDateTime> list = new List<MyGridDateTime>();
int i = 0;
foreach (string hour in hoursCollection)
{
list.Add(new MyGridDateTime {Hour = hour, Date = dateCollection[i], Message = messageCollection[i]};
i++;
}
grid.DataSource = list;
}
Note this only works if all of your Lists contain similiar amount of data. Else you need to update this a bit to become string.empty instead of Exception if your Lists are not of the same size.

Generate lambda expression from string

I have a need to store lambda expressions in a database and execute them dynamically. The following snippet works well as is,
float result = dataRowArray.AsEnumerable().Sum(r => r.Field<float>("ColumnA") * r.Field<float>("ColumnB"));
but I'd like to store the following part in a string...
r => r.Field<float>("ColumnA") * r.Field<float>("ColumnB")
... and inject it dynamically as in:
float result = MySession.Current.dr.AsEnumerable().Sum(storedLambdaString);
I've done a ton of Googling but I'm coming up short. Any suggestions?
I suggest store the query in the database and execute using LINQ like below.
using (eEntities db = new eEntities())
{
string query = "select name,age,salary from employees"
var employees = db.Database.SqlQuery<Employee>(query).
}
Please note: Employee is here my custom class having properties same as queried.
Theres a nuget package that may help you "System.Linq.Dynamic". This sample code works...
public class TestRow
{
public Dictionary<string,float> Field { get; set; }
public TestRow()
{
this.Field = new Dictionary<string, float>();
this.Field.Add("ColumnA", 2);
this.Field.Add("ColumnB", 3);
}
}
class Program
{
static void Main(string[] args)
{
var testRow = new TestRow();
string expressionString = "r.Field[\"ColumnA\"] * r.Field[\"ColumnB\"]";
var parameter = Expression.Parameter(typeof(TestRow),"r");
var lambdaET = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { parameter }, typeof(float), expressionString);
var result = lambdaET.Compile().DynamicInvoke(testRow);
Console.WriteLine(result);
Console.ReadLine();
}
}

How to pick second column from a PetaPoco query result?

Below is my code:
string Query = "SELECT EmpName, EmpCode FROM EmpDetail WHERE ZCode=101 ORDER BY EmpName";
var db = new PetaPoco.Database("conCustomer");
var result = db.Fetch<string>(query);
TextBox1.Text = result.ToString(); //This is giving first column
TextBox2.Text = .... // pick second column
I want to know how to pick the second column from the result.
I believe the issue you're having is that you're not using a class as part of the fetch. Try creating a simple class and performing the fetch with that:
public class EmpDetail
{
public string EmpName { get; set; }
public string EmpCode { get; set; }
}
var result = db.Fetch<EmpDetail>(Query);
Then try iterating over that list of EmpDetail:
foreach (var detail in result)
{
var x = detail.EmpName; // First column
var y = detail.EmpCode; // Second column
}
EDIT: According to this (h/t Robert Koritnik), it does look like it will support a dynamic query like so (untested):
foreach (var detail in db.Fetch<dynamic>(query))
{
var x = detail.EmpName; // First column
var y = detail.EmpCode; // Second column
}

Categories