export null values to xml from a dataset - c#

If you have a null value in a field in a dataset and export it to xml it does "remove" the field tag .. anyway to avoid this..

An empty tag does not have the same meaning as null, especially for strings. How would you make the difference if the tag was present but empty?

//Try changing values of cells.
foreach (DataRow row in dtPr.Rows)
{
for (int i = 0; i < dtPr.Columns.Count; i++)
{
dtPr.Columns[i].ReadOnly = false;
if (string.IsNullOrEmpty(row[i].ToString()))
{
if (dtPr.Columns[i].DataType == typeof(string))
row[i] = string.Empty;
else if (dtPr.Columns[i].DataType == typeof(int))
row[i] = 0;
else if (dtPr.Columns[i].DataType == typeof(DateTime))
row[i] = new DateTime(1753, 1, 1);
}
}
}

Think of NULL as a state and everything else as a value. So if you want a blank value, just send in an empty string (single white space)

you have to paint your method with an attribute that tells it to stay there. not near my winblows machine so cant give you the actual code. but would look something like this,
[XMLElement(IsNullable = true)]
myProperty {get;set;}

Related

Set values order based off other values logic

How can I more efficiently check for null values and set their order accordingly?
I have 3 fields (1, 2, 3) and I need to do a check to see if any of the string values are null and if so I need to move the respective value up to the next spot so if 2 is null but 3 is not I will need to move 3 into 2's spot.
My original thought was to do this with a series of if statements however after starting down that road I'm learning that my list of if statements is going to be substantial so I'm looking for a better way to preform this check and set my values.
if (string.IsNullOrEmpty(field1))
{
fields.SetField("Field1", field1);
fields.SetField("Field2", field2);
}
If I continued down the above route I would have to also preform a check for field 2 and 3 and etc... for each initial check.
Maybe you could use this logic:
string firstNotNull = field1 ?? field2 ?? field3;
if (string.IsNullOrEmpty(field1)) fields.SetField("Field1", firstNotNull);
if (string.IsNullOrEmpty(field2)) fields.SetField("Field2", firstNotNull);
if (string.IsNullOrEmpty(field3)) fields.SetField("Field3", firstNotNull);
But the logic is not entirely clear. Do you also want to overwrite Field3 with a value from Field1 if the Field3 is null and Field1 not?
Maybe this generic approach is what you're looking for:
var stringColumns = table.Columns.Cast<DataColumn>().Where(c => c.DataType == typeof(string)).ToList();
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < stringColumns.Count; i++)
{
string field = row.Field<string>(i);
if (string.IsNullOrEmpty(field))
{
// check all after this:
for (int ii = i + 1; ii < stringColumns.Count; ii++)
{
string nextField = row.Field<string>(ii);
if (!string.IsNullOrEmpty(nextField))
{
row.SetField(i, nextField);
break;
}
}
}
}
}
If 'fields' is an IEnumerable collection of strings, you could simply call the Orderby() / OrderByDescending() method on it.
var sortedFields = fields.OrderBy(s => s);
// OR
var sortedFields = fields.OrderByDescending(s => s)

Make null columns invisible in DataGridView

I have a datagridview in WinForm C# application called custFleetDataGrid
I've tried to create a method which will set each column to invisible if all the rows are null or ""
The code does not work as expected, columns with blank data remain in the grid view.
I'm calling Code like this
custFleetDataGrid.RemoveEmptyColumns();
Method I'm using to remove NullColumns
public static class ExtensionGridView
{
public static DataGridView RemoveEmptyColumns(this DataGridView grdView)
{
foreach (DataGridViewColumn clm in grdView.Columns)
{
bool notAvailable = true;
foreach (DataGridViewRow row in grdView.Rows)
{
if (row.Cells[clm.Index].Value == null || row.Cells[clm.Index].Value.ToString() != "")
{
notAvailable = false;
break;
}
}
if (notAvailable)
{
grdView.Columns[clm.Index].Visible = false;
}
}
return grdView;
}
}
could this be because the compiler is trying to convert a null value to a string?
Correct, that's the exact case. Just it's not the compiler, but the code you have written.
I would suggest you encapsulating the empty cell logic into separate extension method inside the ExtensionGridView class:
public static bool IsEmpty(this DataGridViewCell cell)
{
var value = cell.Value;
return value == null || value == DBNull.Value || (value as string) == string.Empty;
}
Then you can use simple LINQ to determine the empty columns:
public static IEnumerable<DataGridViewColumn> EmptyColumns(this DataGridView gridView)
{
return gridView.Columns.Cast<DataGridViewColumn>()
.Where(c => gridView.Rows.Cast<DataGridViewRow>().All(r => r.Cells[c.Index].IsEmpty()));
}
Then your method could be simply like this:
public static DataGridView RemoveEmptyColumns(this DataGridView gridView)
{
foreach (var column in gridView.EmptyColumns())
column.Visible = false;
return gridView;
}
If Value is null, you'll get a NullReferenceException if using ToString() on it. So you have to null-check the value before using ToString().
Go like this:
// IF (Value is empty => use "").ToString() <-- IsNullOrEmpty
if (!string.IsNullOrEmpty(row.Cells[clm.Index].Value ?? "").ToString())
{
notAvailable = false;
break;
}
Check the details about ?? here.
Its the same as:
// If not null
if(row.Cells[clm.Index].Value != null)
{
// If string of value is empty
if(row.Cells[clm.Index].Value.ToString() != "")
{
notAvailable = false;
break;
}
}
Away from your problem here's a short version of everything:
public static DataGridView RemoveEmptyColumns(this DataGridView grdView)
{
for (int i = 0; i < grdView.ColumnCount; i++)
{
// On each iteration get all values of a column
IEnumerable<string> column = grdView.Rows.Cast<DataGridViewRow>().Select(row => (string)row.Cells[i].Value);
// If there is no value with length > 0 => visible = false
if (!column.Any(x => x.Length > 0)) { grdView.Columns[i].Visible = false; }
}
return grdView;
}
Instead of iterating trough each row i'd let my select statement do it like so:
SELECT some columns FROM yourtable WHERE thecolumn IS NOT NULL
Your problem is that you are checking if row.value.toString() is null or empty. If valueis null, when it tries to get the toString() to check if its null or empty it can't.
Change your if statement to:
if (row.Cells[clm.Index].Value != null || row.Cells[clm.Index].Value.toString()!="")
{
//Code
}
Important note:
In C# (and most modern languages) you have two opetaors for OR (| and ||) and two for AND(& &&). If its just one (&/|) it will check both sides but if it have two (&&/||) if the first condetin determines eveirthing (a true for OR or a false for AND) it will not check the second one.
This gives you more rendiment but also is usefull for not having nullpointerexeptions. If it's null, it will not check the second part and it will not explote. If you just put one it will say "Yes, is null, lets check if the string is also "" and will throw a NulPointerExeption.

C# NetSuite WebServices: Get value from custom field in saved search (ItemSearchAdvanced)

I'm using C# MVC to connect to NetSuite using their WebServices API. I have some current code that calls a saved search of inventory items. Here is the current code that is working perfectly:
ItemSearchAdvanced searchItems = new ItemSearchAdvanced();
searchItems.savedSearchId = "128";
SearchResult result = netSuiteSvc.search(searchItems);
int totalRecords = 0;
int processedRecords = 0;
UpdateNetsuitePriceListModel returnObj = new UpdateNetsuitePriceListModel();
returnObj.NewPriceList = new List<NetSuitePriceListRecord>();
if (result.status.isSuccess)
{
SearchRow[] searchRows = result.searchRowList;
if (searchRows != null && searchRows.Length >= 1)
{
for (int i = 0; i < searchRows.Length - 1; i++)
{
ItemSearchRow itemRow = (ItemSearchRow)searchRows[i];
if (itemRow.basic.itemId != null && itemRow.basic.mpn != null && itemRow.basic.basePrice != null && itemRow.basic.salesDescription != null)
{
returnObj.NewPriceList.Add(new NetSuitePriceListRecord()
{
ItemId = itemRow.basic.itemId[0].searchValue,
ManufacturerPartNumber = itemRow.basic.mpn[0].searchValue,
ContractPrice = Convert.ToDecimal(itemRow.basic.basePrice[0].searchValue),
Cost = CalculateProductCostForIngram(Convert.ToDecimal(itemRow.basic.basePrice[0].searchValue)),
Description = itemRow.basic.salesDescription[0].searchValue
});
processedRecords++;
}
totalRecords++;
}
}
else
{
throw new Exception("NetSuite Part List Blank");
}
}
else
{
throw new Exception("NetSuite Part List Search Failure");
}
Now I have need to pull the itemId from a custom added field rather than the default itemId field.
Obviously since this is a custom field it isn't a property of ItemSearchRowBasic. It looks like instead of the property I can choose "customFieldList" which is an array of "SearchColumnCustomField". If I choose an index for the array I can see that SearchColumnCustomField contains:
customLabel
internalId
scriptId
I imagine I should be able to get the internalId of the SearchColumnCustomField and somehow use that to get the search value for that custom column but I've had some trouble finding any examples that fit so far.
This custom field is a free form text field added to all inventory items.
Try setting scriptId with the ID of the field ("custitem_xyz"). That should work.
Before 2013 one would use internalId, but since then it changed to scriptId.
You would need to loop over the CustomRecord items in the customFieldList. I then usually check for a specific type so I can cast to the correct object, but with some reflection you could probably avoid that.
foreach (Record r in mySearchResponse.recordList){
foreach (CustomFieldRef cr in ((CustomRecord)r).customFieldList){
if (cr.GetType().Name == "SelectCustomFieldRef"){
if (((SelectCustomFieldRef)cr).scriptId == "my_custom_field"){
internalID = ((CustomRecord)r).internalId;
}
}
}
}

Checking for empty string before inserting the record

I am custom importing some rows from a text file to our database and so I have bunch of codes like this for many fields.
address.State = row["Location State"].ToString();
I just noticed a requirement that says
don't overwrite those fields in the value that we are reading from the
text file is empty or blank.
So I assume I can wrap them all around a check like this?
if(!String.IsNullOrEmpth(row["Location State"].ToString()))
address.State = row["Location State"].ToString();
But before I go ahead and apply this kind of logic around all those fields I wanted to check and see if you have better solutions?
Maybe an extension method could help here:
public static string ColumnValueOrDefault(this DataRow row, string column, string defaultValue)
{
if (row == null)
{
throw new ArgumentNullException("row");
}
if (column == null)
{
throw new ArgumentNullException("column");
}
if (defaultValue == null)
{
throw new ArgumentNullException("defaultValue");
}
var rowString = row[column].ToString();
return string.IsNullOrEmpty(rowString) ? defaultValue : rowString;
}
Address.State = row.ColumnValueOrDefault("column", Address.State);
I would (and do) use this pattern personally :
string sTester = string.Empty
Address.State = string.IsNullOrEmpty(sTester = row["collumn"].ToString()) == false ? sTester : Address.State;
This allows each collumn value to be set once, and the reused using the same string variable, and is relatively readable

.Add(null) would break my list<string>. I would like to add in a condition to replcae null with a string

I ran into quite an interesting issue. In conclusion, I learned that empty and null are two different things.
I am currently creating a constructore that takes stores two List<string>s.
public ValueList(List<string> firstList, List<string> secondList) {
for (int i = 0; i < firstList.Count; i++) {
// Checks for nulls.
if(firstList[i] == null){
_firstList.Add("null");
}else if (secondList[i] == null){
_secondList.Add("null");
}else{
_firstList.Add(firstList[i].ToString());
_secondList.Add(secondList[i].ToString());
}
}
}
There are times where this constructor would read Excel files, and in any blank square, the other script I use would parse in a null value. The null value would break my script entirely, and not .Add() anything.
So I tried to put in my null-check conditions. If that particular index is a null, then we add a "null" string.
However, the null continues to break my script.
I was wondering if there is a more elegant and fool-proof way to combat this issue? I think I have also tried .Equals(null) but that did not solve the issue at all.
The proper logic would be
for (int i = 0; i < firstList.Count; i++) {
// Checks for nulls.
if(firstList[i] == null){
_firstList.Add("null");
}
else {
_firstList.Add(firstList[i].ToString());
}
if (secondList[i] == null){
_secondList.Add("null");
}
else{
_secondList.Add(secondList[i].ToString());
}
}
But you could just to a Linq projection:
_firstList = firstList.Select(s => s ?? "null").ToList();
_secondList = secondList.Select(s => s ?? "null").ToList();
EDIT
Since you do want to store nulls you just need to not call ToString:
for (int i = 0; i < firstList.Count; i++) {
_firstList.Add(firstList[i]);
_secondList.Add(secondList[i]);
}

Categories

Resources