I am trying to add a few rows I got from a DataTable to my list using this struct:
protected struct roleProperties
{
public string roleName { get; set; }
public string[] functionTitle { get; set; }
}
As you can see I want more strings inside the method Title string
I have been trying to do it like this:
public void getRoleFuncs(int roleId)
{
List<roleProperties> roles = new List<roleProperties>();
int i = 1;
SqlParameter ro_id = new SqlParameter("#ro_id", roleId);
string q = "SELECT ro_name, fu_title FROM roles INNER JOIN rolefunctions ON roles.ro_id = rolefunctions.fk_role_id INNER JOIN functions ON rolefunctions.fk_func_id = functions.fu_id WHERE ro_id = #ro_id";
SqlDataReader r = gm.returnReader(q, ro_id);
while (r.Read())
{
roleProperties item = new roleProperties();
item.roleName = r["ro_name"].ToString();
foreach (IDataRecord str in r)
{
item.functionTitle[i] = r["fu_title"].ToString();
i++;
}
roles.Add(item);
}
}
But I get a null reference on this line:
item.functionTitle[i] = r["fu_title"].ToString();
Can anyone see what I am doing wrong?
item.functionTitle is null because arrays are reference types and you have not initialized the property anywhere (so it has the default value: null for a reference type).
Even if that was not a problem (let's say functionTitle is an empty array) item.functionTitle[i] would again throw because it tries to access an index that is out of bounds. And finally, you have an off-by-one error: the first element in an array has the index 0, not 1.
You can fix all of the above by changing the code to
while (r.Read())
{
roleProperties item = new roleProperties();
item.roleName = r["ro_name"].ToString();
item.functionTitle = r.Select(o => o["fu_title"].ToString()).ToArray();
roles.Add(item);
}
Your array is not initialized and hence null since you do not know the size of the array you are going to need it seems a more suitable approach to use a list instead
change your struct to
protected class roleProperties
{
public string roleName { get; set; }
public IList<string> functionTitle { get; private set;}
public roleProperties(){
functionTitle = new List<string>();
}
}
and then change
item.functionTitle[i] = r["fu_title"].ToString();
to
item.functionTitle.Add(r["fu_title"].ToString());
I've changed the struct to a class because it's mutable and mutable structs are evil.
Initialize the array first.
item.functionTitle = new string[n]; // where n is an int
Related
The test should check when a train is assigned to a line he losts its previous line. The class Train should implement this test in the function public void AssignTo(ILine l) by following those steps (they need to be respected):
Current assignment = l1
l1.Trains contains THIS
need to remove THIS from l1.trains
need to change current line and add train to new line
internal class Train : ITrain
{
internal Train(string name, Company company)
{
this.Name = name;
this.Company = company;
}
public string Name
{
get;
}
public ICompany Company
{
get;
}
public ILine Assignment
{
get;
private set;
}
public void AssignTo(ILine l)
{
//Current assignment = l1
var l1 = Assignment;
//l1,Trains contains THIS
this.AssignTo(l1.train)
//need to remove THIS from l1.trains
((List<Train>)l1.Trains).Remove(this);
//need to change current line and add train to new line
((List<Train>)l.Trains).Add(this);
Assignment = l;
}
}
}
[Test]
public void T2_when_a_train_is_assigned_to_a_line_he_losts_its_previous_line()
{
ICity s = CityFactory.CreateCity("Paris");
ICompany c = s.AddCompany("SNCF");
ILine l1 = s.AddLine("RER A");
ILine l2 = s.AddLine("RER B");
ITrain t1 = c.AddTrain("RER1");
t1.AssignTo(l1);
t1.Assignment.Should().BeSameAs(l1);
t1.AssignTo(l2);
t1.Assignment.Should().BeSameAs(l2);
l1.Trains.Count().Should().Be(0);
l2.Trains.Single().Should().BeSameAs(t1);
}
The problem with your current interfaces are that ILine.Trains is an IEnumerable, and you can't really remove something from an IEnumerable. In your code, you have assumed that it will always be a List, which you shouldn't really do, but if you can't change the type of ILine.Trains then I guess that's the only way.
Anyway, the reason why your code doesn't work is that you are recursively calling AssignTo for some reason. You should remove this call:
public void AssignTo(ILine l)
{
var l1 = Assignment;
// remove this line
// this.AssignTo(l1.train)
((List<Train>)l1.Trains).Remove(this);
((List<Train>)l.Trains).Add(this);
Assignment = l;
}
Although this isn't required, (it seems to be one of your requirements), you need to check whether l1.Trains contains this first:
var l1 = Assignment;
if (l1.Trains.Contains(this)) {
((List<Train>)l1.Trains).Remove(this);
}
((List<Train>)l.Trains).Add(this);
Assignment = l;
I have two variables that contain true/false data. THe first variable can be null but the second variable is always non null. Both variables will always be the same length.
var AnswerGridCorrect = "000111"; // or null
var AnswerGridResponses = "000011";
How could I change this data into an object oriented form. I already created classes and these are below. Here's is what I need the output to look like when converted to JSON:
"answers":[ // Json conversion made Answers into answers
{"correct":null,"response":true},
{"correct":null,"response":true},
{"correct":null,"response":true},
{"correct":null,"response":false}
}
Note that I am using LINQ to output the data so I think what I need is a function with parameters something like this:
.Select((t, index) => new {
Answer = t.Answer,
Answers = makeAnswer(t.AnswerGridCorrect,
t.AnswerGridResponses)
});
I am not sure if this helps but here were the classes I was using when I did this from JSON:
public class AnswerRow
{
public bool? Correct { get; set; }
public bool Response { get; set; }
}
public class AnswerRowList
{
public IList<AnswerRow> AnswerRows { get; set; }
}
Here is an implementation for your makeAnswers method:
public List<AnswerRow> makeAnswers(string c, string r)
{
var result = new List<AnswerRow>();
for(var i=0; i<r.Length; i++)
{
result.Add(
new AnswerRow {
Correct = c!=null?new Nullable<bool>(c[i]=='1'):null,
Response = r[i]=='1'
});
}
return result;
}
Rene's answer is probably correct, but here's the (unnecessarily complex) Linq way:
AnswerRowList MakeAnswer(string answerGridCorrect, string answerGridResponses)
{
return new AnswerRowList()
{
AnswerRows = answerGridResponses.Zip(
answerGridCorrect == null ?
Enumerable.Repeat<bool?>(null, answerGridResponses.Length) :
answerGridCorrect.Select(x => new Nullable<bool>(x == '1')),
(r, c) => new AnswerRow()
{
Correct = c,
Response = r == '1'
}).ToList()
};
}
i have a list
List<PossibleSolutionCapacitors> PossibleSolution = new List<PossibleSolutionCapacitors>();
here is its class
class PossibleSolutionCapacitors
{
public int CapacitorALocation { get; set; }
public int CapacitorBLocation { get; set; }
public int CapacitorCLocation { get; set; }
}
i have 3 integers
int A;
int B;
int C;
i need to check if any combination of A,B,C is contained in the list possible solutions
i.e if the following are in the list (Boolean saying true/false is enough)
A,B,C
A,C,B
B,A,C
etc...
is this possible ?
thanks
Damo
A variation on Save's solution:
var fixedSet = new HashSet<int>(){A,B,C};
bool result = PossibleSolutions.Any(x => fixedSet.SetEquals(
new[] { x.CapacitorALocation,x.CapacitorBLocation,x.CapacitorCLocation }));
var query = PossibleSolution.Any(x=>HashSet<int>.CreateSetComparer()
.Equals(new HashSet<int>(){A,B,C}
,new HashSet<int>(){x.CapacitorALocation,x.CapacitorBLocation,x.CapacitorCLocation}));
To save some time, you can create the HashSet<int>(){A,B,C} and the comparer beforehand, and call it in your code, with something like:
var fixedSet = new HashSet<int>(){A,B,C};
IEqualityComparer<HashSet<int>> comparer = HashSet<int>.CreateSetComparer();
var query = PossibleSolution.Any(
x=>comparer.Equals(fixedSet,new HashSet<int>(){x.CapacitorALocation,x.CapacitorBLocation,x.CapacitorCLocation}));
And finally, for a version that uses SetEquals instead of the comparer, check Thomas Levesque solution.
I have issue in the following code. Below is my model code
public class Comments
{
public string displayComments { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime? dTime { get; set; }
public int airPortId { get; set; }
}
public class LstComments
{
private List<Comments> _lstcomment = new List<Comments>();
public List<Comments> lstCommet
{
get
{
return _lstcomment;
}
set
{
_lstcomment = value;
}
}
}
and in mycontroller am getting data from EF and adding it to the properties in For loop. Code Below
Comments com = new Comments();
LstComments savedComments = new LstComments();
AirportEntities airPortEntity = new AirportEntities();
var userComments = from c in airPortEntity.AirportComments
select c;
//List<Comments> savedComments = new List<Comments>();
foreach (var item in userComments)
{
com.displayComments = item.Comments;
com.dTime = item.Time;
savedComments.lstCommet.Add(com);
}
My issue is my entire list is getting updated with same records(recently added data)
For eg. foreach 3rd timn updates both 1st and 2nd 3rd item in list with 3rd item data.
What i am doing wrong ?
You instantiate Comments outside of the loop. This means there are a bunch of references to the same comment object on the heap. You need to do
Comments com = new Comments(); inside of the foreach. This will create a separate instance on each iteration, instead of just giving the one instance new values.
you need to instantiate Comments com = new Comments(); each time in foreach. As for now you just rewrite reference to the same object.
Or which is better to rewrite foreach as:
foreach (var item in userComments)
{
savedComments.lstCommet.Add(
new Comments()
{
com.displayComments = item.Comments,
com.dTime = item.Time
});
}
I have in a SearchFlyClass an Arraylist GetFly()
...
public ArrayList GetFly(int tip, string country)
{
...
var list = new ArrayList();
var reader = command.ExecuteReader();
if (reader.HasRows)
{
...
while (reader.Read())
{
decimal nr_zbor = reader.GetDecimal(cod_zbor);
string aeroport = reader.GetString(nume_aeroport);
string companie = reader.GetString(nume_companie);
list.Add(nr_zbor);
list.Add(companie);
list.Add(aeroport);
}
}
...
and I wish to put in Form1.cs the list in listview by columns[zbor(colZbor),airport(colAirport),company(colCompany)], but I don't now how
private SearchFlyClass searchFly = new SearchFlyClass();
private ArrayList fly = new ArrayList();
...
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem searchlist = new ListViewItem();
searchlist.Items.Add(new ListViewItem(elem));
}
}
can someone help me, please?
First you have to put ListView to View mode details, which you do with following code (it is also possible with setting View property in designer):
ListView listView = new ListView();
listView.View = View.Details;
Then you have to assign columns to the listView (can also be done in designer):
listView.Columns.Add("zbor");
listView.Columns.Add("airport");
listView.Columns.Add("company");
After this you have to assign other columns to ListViewItem subitems, by modifying your function:
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem listViewItem = new ListViewItem(zbor);
listViewItem.SubItems.Add(airport);
listViewItem.SubItems.Add(companie);
listView.Items.Add (listViewItem);
}
}
The function assumes that it is in Form1.cs and that you have listView variable instantized as class variable of type ListView. Basics of C# and object oriented programming.
There are lots of issues with this code. Firstly, is there any reason that you're using ArrayList instead of the generic collection types? E.g. List<T>
Secondly, I would create a type to store all of the related data for one instance of your entity, rather than putting the column values for the entity into an untyped collection.
Thirdly, your aren't referencing count anywhere in your for loop - presumably because the query is returning a single entity, and therefore the for loop is redundant because you know the number of items returned for a single entity. You are also using a variable elem which doesn't seem to have been defined.
Updated
Define a type that describes your entity:
public class Flight
{
public decimal Code { get; set; }
public string Company { get; set; }
public string Airport { get; set; }
}
Change your method to return an instance of your entity:
public Flight GetFlight(int tip, string country)
Create a new instance to return from the method and populate it from your database query result:
var flight = new Flight();
flight.Code = reader.GetDecimal(cod_zbor);
flight.Airport = reader.GetString(nume_aeroport);
flight.Company = reader.GetString(nume_companie);
return flight;
Now your other method can use the updated method:
var flight = searchFly.GetFlight(...);
// access flight properties here
This assumes that your query returns a single entity. If it returns a collection, then you can use List<Flight> or IEnumerable<Flight> as your return type as appropriate.