Trouble passing value array into an Object array - c#

I am trying to pass an array of values into an array of a table object so that I can write them to the database.
My database looks like this ->
tblCaseNotes
CaseNoteID | PersonId | etc, etc
tblCaseNotesContactType
rowguid | CaseNoteID | ContactTypeID
tblMaintItems
itemID | CategoryID
The itemID from the Maint table is what is being written to the tblCaseNotesContactType along with the current CaseNoteID. There can be multiple ContactTypes per CaseNote.
What I have so far is an array of the Values for the CheckListBox ContactType created in my btnNew_Click Event:
// Contact Type check list box
int cTypeCount = chkContactType.CheckedItems.Count;
int [] contactTypes = new int[cTypeCount];
// reusable generic counter for looping thru the check lists
int cMaintCounter = 0;
foreach (int checkedItem in chkContactType.CheckedIndices)
{
contactTypes[cMaintCounter] = (int)chkContactType.GetItemValue(checkedItem);
cMaintCounter++;
}
CurrentCaseNote.AddCNote(Program._CurrentPerson.PersonID, Convert.ToDecimal(tbxTimeSpentUnits.Text), chkIsCaseLog.Checked, Convert.ToDateTime(datContactDate.Text), memContactDetails.Text, contactTypes);
Which I then pass to my CurrentCaseNote object AddCNote method.
public static void AddCNote(int personID, decimal tsUnits, bool isCaseLog, DateTime cDate, string cDetails, int[] cTypes)
{
var caseNoteToAdd = new tblCaseNote
{
CaseNoteID = Guid.NewGuid(),
PersonID = personID,
TimeSpentUnits =tsUnits,
IsCaseLog =isCaseLog,
ContactDate =cDate,
ContactDetails =cDetails,
InsertDate = DateTime.Now,
InsertUser = Environment.UserName
};
tblCaseNotesContactType[] cTypeToAdd = new tblCaseNotesContactType[cTypes.Length];
cTypeToAdd[0].CaseNoteID = caseNoteToAdd.CaseNoteID;
cTypeToAdd[0].ContactTypeID =cTypes[0];
cTypeToAdd[0].rowguid = Guid.NewGuid();
CaseNoteDAL.addCNote(caseNoteToAdd,cTypeToAdd);
It is then passed to the DAL to be written to the local database:
public static void addCNote(tblCaseNote caseNote, tblCaseNotesContactType[] cType)
{
foreach (var type in cType)
{
caseNote.tblCaseNotesContactTypes.Add(type);
}
dcCaseNotes.tblCaseNotes.InsertOnSubmit(caseNote);
//dcCaseNotes.tblCaseNotes.InsertOnSubmit(caseNoteToAdd);
dcCaseNotes.SubmitChanges();
}
It is giving me a NUllReferenceException was unhandled error on this line -->cTypeToAdd[0].CaseNoteID = caseNoteToAdd.CaseNoteID;
Is it because I am only working with the [0]? I just did that to simplify my testing of this. When I step through the code my value array is correct and there is a Guid for caseNoteToAdd.CasNoteID
Can someone give me a few pointers on where I am going wrong here and what might be causing the error? As you can tell from my code I am new to this and I am learning on the fly.
Thanks,
~P

The problem is that you've created an array of reference types, but not populated it.
In other words, after this line:
tblCaseNotesContactType[] cTypeToAdd = new tblCaseNotesContactType[cTypes.Length];
you've got an array of null references - the value of each element is null.
You then need to write:
cTypeToAdd[0] = new tblCaseNotesContactType();
(or a similar statement) before you can start changing its properties.
An alternative would be to use an object initializer and do it in one statement (after creating the array):
cTypeToAdd[0] = new tblCaseNotesContactType
{
CaseNoteID = caseNoteToAdd.CaseNoteID,
ContactTypeID =cTypes[0],
rowguid = Guid.NewGuid()
}:

Related

C# - Nested Array/Data structures

Recently, I have been getting into C# (ASP.NET) and moving on from PHP. I want to achieve something like this:
mainArray (
array 1 (
'name' => 'example'
),
array 2 (
'name' => 'example2'
)
);
I know that you can use an Array in C# however, you must indicate the length of the Array before doing so which is where the problem is.
I want to loop through a Database in a Class function which returns an Array of all the columns, ie:
id, username, email.
I have tried:
public Array search_bustype(string match, string forthat)
{
db = new rkdb_07022016Entities2();
var tbl = (from c in db.tblbus_business select c).ToArray();
List<string> List = new List<string>();
int i = 0;
foreach (var toCheck in tbl)
{
if (toCheck.BusType.ToString() == match)
{
if (forthat == "Name")
{
List.Add(toCheck.Name);
}
if (forthat == "Address")
{
}
}
i++;
}
return List.ToArray();
}
But as you can see, I am having to only return the single column because the List is not multidimensional (can't be nested).
What can I use to solve this issue? I have looked at some links:
C# Arrays
StackOverflow post
But these again are an issue for my structure since I don't know how many index's I need in the Array when declaring it - The Database grows everyday.
Thanks in advance.
Try something like this. First, define a class for your business model.
public class Person
{
public string Name {get;set;}
public string Address {get;set;}
}
Then use a generic list instead of a string list.
public Person[] search_bustype(string match, string forthat)
{
var db = new rkdb_07022016Entities2();
List<Person> personList = new List<Person>();
foreach (var toCheck in db.tblbus_business.Where(b => b.BusType.ToString() == match))
{
var model = new Person { Name = toCheck.Name, Address = toCheck.Address };
personList.Add(model);
}
return personList.ToArray();
}
I'm not sure what you are trying to do with the forthat variable.
You can use a list of lists
IList<IList<string>> multiList;

Updating entire node with mutating cypher in Neo4jclient

I need to update all the properties of a given node, using mutating cypher. I want to move away from Node and NodeReference because I understand they are deprecated, so can't use IGraphClient.Update. I'm very new to mutating cypher. I'm writing in C#, using Neo4jclient as the interface to Neo4j.
I did the following code which updates the "Name" property of a "resunit" where property "UniqueId" equals 2. This works fine. However,
* my resunit object has many properties
* I don't know which properties have changed
* I'm trying to write code that will work with different types of objects (with different properties)
It was possible with IGraphClient.Update to pass in an entire object and it would take care of creating cypher that sets all properies.
Can I somehow pass in my object with mutating cypher as well?
The only alternative I can see is to reflect over the object to find all properties and generate .Set for each, which I'd like to avoid. Please tell me if I'm on the wrong track here.
string newName = "A welcoming home";
var query2 = agencyDataAccessor
.GetAgencyByKey(requestingUser.AgencyKey)
.Match("(agency)-[:HAS_RESUNIT_NODE]->(categoryResUnitNode)-[:THE_UNIT_NODE]->(resunit)")
.Where("resunit.UniqueId = {uniqueId}")
.WithParams(new { uniqueId = 2 })
.With("resunit")
.Set("resunit.Name = {residentialUnitName}")
.WithParams(new { residentialUnitName = newName });
query2.ExecuteWithoutResults();
It is indeed possible to pass an entire object! Below I have an object called Thing defined as such:
public class Thing
{
public int Id { get; set; }
public string Value { get; set; }
public DateTimeOffset Date { get; set; }
public int AnInt { get; set; }
}
Then the following code creates a new Thing and inserts it into the DB, then get's it back and updates it just by using one Set command:
Thing thing = new Thing{AnInt = 12, Date = new DateTimeOffset(DateTime.Now), Value = "Foo", Id = 1};
gc.Cypher
.Create("(n:Test {thingParam})")
.WithParam("thingParam", thing)
.ExecuteWithoutResults();
var thingRes = gc.Cypher.Match("(n:Test)").Where((Thing n) => n.Id == 1).Return(n => n.As<Thing>()).Results.Single();
Console.WriteLine("Found: {0},{1},{2},{3}", thingRes.Id, thingRes.Value, thingRes.AnInt, thingRes.Date);
thingRes.AnInt += 100;
thingRes.Value = "Bar";
thingRes.Date = thingRes.Date.AddMonths(1);
gc.Cypher
.Match("(n:Test)")
.Where((Thing n) => n.Id == 1)
.Set("n = {thingParam}")
.WithParam("thingParam", thingRes)
.ExecuteWithoutResults();
var thingRes2 = gc.Cypher.Match("(n:Test)").Where((Thing n) => n.Id == 1).Return(n => n.As<Thing>()).Results.Single();
Console.WriteLine("Found: {0},{1},{2},{3}", thingRes2.Id, thingRes2.Value, thingRes2.AnInt, thingRes2.Date);
Which gives:
Found: 1,Foo,12,2014-03-27 15:37:49 +00:00
Found: 1,Bar,112,2014-04-27 15:37:49 +00:00
All properties nicely updated!

How to add multiple data types to list

I have my list as below,
var serie_line = new { name = series_name , data =new List<float?>() };
In the above code data in another list which contains float value, I want data to contains two different datatype value that is string and float value, when I am trying to add two different datatype values as follow,
var serie_line = new { name = series_name , data =new List<string, float?>() };
It gives me an error as
Using the generic type'System.Collections.Generic.List<T>' requires 1 argument.
I cannot try for data=new List<Tupple<string,float>>();..since I am using .NET 3.5...any idea..hw cn I deal with this problem..thank you,
----------Updated question---------
Output that I requires is as follows,
{
"legend":{"enabled":"true"},
"title":{"text":"Financial"},
"chart":{"type":"pie"},
"series":
[
{"name":"Actual-","data":[["Market Share",20.00],["Sales Growth",30.00],["Operating Profit",40.00],["Actual-Gross Margin %",10.00]]}
]
},
this data list should contains one string value and one float value...I want to draw pie chart in highcharts but output I am getting is as follows,
{
"legend":{"enabled":"true"},
"title":{"text":"Financial"},
"chart":{"type":"column"},
"series":[{"name":"Actual","data":[{"Str":"Market Share","Flo":20.00}]},
{"name":"Actual","data":[{"Str":"Sales Growth","Flo":30.00}]},
{"name":"Actual","data":[{"Str":"Operating Profit","Flo":40.00}]},
{"name":"Actual","data":[{"Str":"Gross Margin %","Flo":10.00}]}
]
}
Any Idea...???
----------Use of Dictionary----------
var data = new Dictionary<string, float?>();
var serie_line = new { name = series_name, data };
serie_line.data.Add(child_object_name, period_final_value);
but this doesnot give required output...
it only gives values inside data as for eg,
"data":["market share":20.00].. since I am serializing serie_line into JSON...but I don't want this way..what I want is "data":["market share",20.00]
I hope u get this...
just use
new Dictionary<string, float?>() //if your string value cannot be duplicated
//or
new List<KeyValuePair<string,float?> >
create a type to be use with your list:
public class MyDataType
{
public string Str {get; set;}
public float? Flo {get;set;}
}
you use it like this:
var serie_line = new { name = series_name , data =new List<MyDataType>() };
serie_line.data.Add(new MyDataType{Flo = 45.4});
or like:
var serie_line = new { name = series_name , data =new List<MyDataType>() };
serie_line.data.Add(new MyDataType{Flo = 45.4, Str = "my string"});
If you are trying to add items to a list so that both are available you need to use List<object>(), as its the only shared type between both. That or use ArrayList.
As you pull the objects out you will need to test if they are objects of type string or float? in order to cast them back. You may be able to wrap them.
Use ArrayList, the non-generic version of List.
How about something more structured:
public struct MyData
{
public float? FloatData;
public string StringData;
}
var serie_line = new
{
name = series_name,
data = new MyData()
{
FloatData = theFloatData,
StringData = theStringData,
}
};

How to set Option List value on new CRM 2011 Entity record with Linq?

I'm creating new Entity records in C#. The problem is my early-bound Xrm class is expecting the integer value of the Option List in question, but all I have is the string value of the Option List.
So, this is what I'd like to do. The problem is the "OptionListValue" in question is the integer value. You know; The auto-created one that's huge.
Is the only way for me to do this by finding out the value of that particular option? If so, what API do I use to get it and how do I use it? I'm expecting there's some Linq method of doing so. But I'm possibly assuming too much.
public void CreateNewContactWithOptionListValue(string lastName, string theOptionListValue)
{
using ( var context = new CrmOrganizationServiceContext( new CrmConnection( "Xrm" ) ) )
{
var contact = new Contact()
{
LastName = lastName,
OptionListValue = theOptionListValue // How do I get the proper integer value from the CRM?
};
context.Create( contact );
}
}
Method to do it without using web service:
generate enums for option sets (here is how you can do it)
once you have enum, just parse string value. Something like this:
public void CreateNewContactWithOptionListValue(string lastName, string theOptionListValue)
{
using (var context = new CrmOrganizationServiceContext(new CrmConnection("Xrm")))
{
new_customoptionset parsedValue;
if (!Enum.TryParse<new_customoptionset>(theOptionListValue, out parsedValue))
{
throw new InvalidPluginExecutionException("Unknown value");
}
var contact = new Contact()
{
LastName = lastName,
OptionListValue = new OptionSetValue((int)parsedValue)
};
context.Create(contact);
}
}
Be careful with space in option labels, as they are removed in enums

Linq To Data set error System.InvalidCastException: Specified cast is not valid

I get the following exception using Linq to data set "System.InvalidCastException: Specified cast is not valid."
The problem is as follows I have a model with two value of type int?. The values in the database are not required so some fields are blank. I have read the table into a data set and now I need to query the data set using the following code.
//model
public class Model
{
// Public Properties
...
...
...
public int? YearBegin { get; set; }
public int? YearEnd { get; set; }
}
//query
var list = from m in data.Tables["Models"].AsEnumerable()
select new Model
{
// rest of members omitted to simplify
YearBegin = m.Field<int>("YearBegin"),
YearEnd = m.Field<int>("YearEnd")
};
I have tried the following none have worked:
m.Field<int?>("YearBegin")
YearEnd = m.IsNull("YearEnd") ? null, m.Field<int>("YearEnd")
Is there another way to check if the field has a value similar to String.IsNullOrEmpty().
Using string as the type is not a possibility...
Thanks
You aren't using a typed DataSet, so my first question would be is the does the DataTable know that those fields are supposed to be 'int?' in the first place, or are they listed as strings? If the DataTable is treating those fields as strings, you will experience that error. The following code assumes a TestData DataSet with a Models DataRow, with two nullable string columns as YearBegin and YearEnd:
using (TestData ds = new TestData())
{
// Typed Rows
ds.Models.AddModelsRow("1", "2");
ds.Models.AddModelsRow(ds.Models.NewModelsRow()); // NULL INFO TEST
// Untyped rows
DataRow r = ds.Models.NewRow();
r[0] = "4";
r[1] = "5";
ds.Models.Rows.Add(r);
//query
var list = from m in ds.Tables["Models"].AsEnumerable()
select new Model
{
// rest of members omitted to simplify
YearBegin = m.Field<int?>("YearBegin"),
YearEnd = m.Field<int?>("YearEnd"),
};
}
That code will encounter the InvalidCastException. However, when I flip the types on the DataTable to nullable Int32, then the nearly identical code works properly:
using (TestData ds = new TestData())
{
// Typed Rows
ds.Models.AddModelsRow(1, 2);
ds.Models.AddModelsRow(ds.Models.NewModelsRow()); // NULL INFO TEST
// Untyped rows
DataRow r = ds.Models.NewRow();
r[0] = 4;
r[1] = 5;
ds.Models.Rows.Add(r);
//query
var list = from m in ds.Tables["Models"].AsEnumerable()
select new Model
{
// rest of members omitted to simplify
YearBegin = m.Field<int?>("YearBegin"),
YearEnd = m.Field<int?>("YearEnd"),
};
}
Take a look at your DataTable. You can correct your issue there. The Field cast to int? will not work unless your DataTable field matches the int? type.
Problem solved, I am working against a legacy access database and the data type was stored as Integer instead on Long Integer meaning it is represented as an Int16 in the data set hence the Invalid cast exception...

Categories