Create struct objects in a for loop - c#

I have some troubls to create an struct object in for loop.
I have an UserData Struct:
public struct UserData
{
public string userID { get; set; }
public string userProjects { get; set; }
public string userAccess { get; set; }
//private List<UserData> list;
public UserData(string id,string project,string access):this()
{
this.userID = id;
this.userProjects = project;
this.userAccess = access;
// list = new List<UserData>();
}
}
So in another Class I try to make a List of my UserData Struct in a for loop:
Class ReadUserData
{
private List<UserData> userdata;
for (int j = 0; j < 4 ; j++)
{
userdata = new List<UserData>() { new
UserData(userID[j.ToString()],
userProject[j.ToString()],
useraccess[j.ToString()]) };
}
var firstuser = userdata.FirstOrDefault();
}
My Problem is that the count from the userData object is 1. It only create 1 object.
Where is my problem can you help?
Thanks

you must add objects to the list using Add method. currently you are overwriting list by putting new list into userdata
Class ReadUserData
{
private List<UserData> userdata = new List<UserData>();// create empty list
for (int j = 0; j < 4 ; j++)
{
userdata.Add(new
UserData(userID[j.ToString()],
userProject[j.ToString()],
useraccess[j.ToString()])); // add objects to the list at each iteration
}
var firstuser = userdata.FirstOrDefault();
}
More about List How to Add.

You are creating a new List<UserData> with ONE item and then you are assigning to userdata object. You are doing that repeatedly in every iteration, that's why.
Try this instead (create the list outside the loop, and Add one item at a time
Class ReadUserData
{
private List<UserData> userdata = new List<UserData>();
for (int j = 0; j < 4 ; j++)
{
userdata.Add( new
UserData(userID[j.ToString()],
userProject[j.ToString()],
useraccess[j.ToString()]) );
}
var firstuser = userdata.FirstOrDefault();
}

Related

c# Getting the Index from an array inside a JSon Object

I'm trying to find out the index of a string in an array within a JObject object. For example, you could give frc610 and it would return 0.
// Get rankings JSON file from thebluealliance.com
string TBArankings = #"https://www.thebluealliance.com/api/v2/district/ont/2017/rankings?X-TBA-App-Id=frc2706:ONT-ranking-system:v01";
var rankings = new WebClient().DownloadString(TBArankings);
string usableTeamNumber = "frc" + teamNumberString;
string team_key = "";
int rank = 0;
dynamic arr = JsonConvert.DeserializeObject(rankings);
foreach (dynamic obj in arr)
{
team_key = obj.team_key;
rank = obj.rank;
}
int index = Array.IndexOf(arr, (string)usableTeamNumber); // <-- This is where the exception is thrown.
Console.WriteLine(index);
// Wait 20 seconds
System.Threading.Thread.Sleep(20000);
Here's the json file I'm using.
I've tried multiple different solutions, none of which worked.
You could just keep the index in variable.
string usableTeamNumber = $"frc{teamNumberString}";
string team_key = "";
int rank = 0;
int index = 0;
int count = 0;
dynamic arr = JsonConvert.DeserializeObject(rankings);
foreach (dynamic obj in arr)
{
team_key = obj.team_key;
rank = obj.rank;
if (usableTeamNumber.Equals(team_key) {
index = count;
}
count++;
}
Console.WriteLine(index);
Create a class that mimics your data structure, like such (only has 3 of the root fields):
public class EventPoints
{
public int point_total { get; set; }
public int rank { get; set; }
public string team_key { get; set; }
}
Then you can Deserialize the object into a list of those objects and you can use LINQ or other tools to query that list:
string teamNumberString = "frc2056";
string TBArankings = #"https://www.thebluealliance.com/api/v2/district/ont/2017/rankings?X-TBA-App-Id=frc2706:ONT-ranking-system:v01";
var rankings = new WebClient().DownloadString(TBArankings);
List<EventPoints> eps = JsonConvert.DeserializeObject<List<EventPoints>>(rankings);
EventPoints sp = eps.Where(x => x.team_key.Equals(teamNumberString)).FirstOrDefault();
Console.WriteLine(eps.IndexOf(sp));
Console.ReadLine();

Is there a way to replace an object which is referenced in multiple lists with a new instance easily?

I would like to replace an object which is referenced in multiple lists with a new instance of matching interface class.
Here is an example to better understand the problem.
There is an interface called IPosition
There are two classes that implement that interface: RealPosition and AccessiblePosition
In my algorithm I am receiving an array of IPosition list, like this: List<IPosition>[], basically multiple lists
It is very common that the lists reference the same instance of an object. Here is a visualisation:
Now I would like to create a new instance of the AccessiblePosition class and update all references in all lists.
Is there a way to do that easily?
Many thanks in advance!
You can create a container for your data.
public interface IContainer<T>
{
T Data { get; set; }
}
And a List<IContainer<IPosition>>.
Now you can change Data of a container instead of changing item references.
You could just iterate through the lists and compare the items.
public interface IPosition
{
int ID { get; set; }
}
public class RealPosition : IPosition
{
public int ID { get; set; }
}
public class AccessiblePosition : IPosition
{
public int ID { get; set; }
}
void Main()
{
var toReplace = new RealPosition { ID = 1 };
var list1 = new List<IPosition>
{
toReplace,
new RealPosition { ID = 2 },
new RealPosition { ID = 3 },
};
var list2 = new List<IPosition>
{
toReplace,
new RealPosition { ID = 4 },
new RealPosition { ID = 5 },
};
var listOfLists = new List<List<IPosition>>{ list1, list2 };
var replacement = new AccessiblePosition{ ID = 42 };
foreach(var list in listOfLists)
{
//must use for here
for(int i = 0; i < list.Count; ++i)
{
if(list[i] == toReplace)
{
list[i] = replacement;
}
}
}
}

list values changes when dataset iteration

I have List of type Date_Check ,I execute a sql query and retrieve the values in a dataset
and I populate the List by iterate through the dataset ,the problem is that when the second iteration towards the list[0],list[1],list[2]... values got the replaced by current object values
Here is my code :
string query = "select Record_Id, Movie_Name from tbl_theater_master ";
DataSet dtst_Theatrs = new DataSet();
dtst_Theatrs = ObjCommon.GetObject.ExecuteQuery_Select(Connection.ConnectionString, query);
if (dtst_Theatrs.Tables[0].Rows.Count != 0)
{
List<Date_Check> lst_Date_Check = new List<Date_Check>();
Date_Check obj_Date_Check = new Date_Check();
for (int i = 0; dtst_Theatrs.Tables[0].Rows.Count > i; i++)
{
obj_Date_Check.Movie_Name = dtst_Theatrs.Tables[0].Rows[i]["Movie_Name"].ToString();
obj_Date_Check.Record_Id = dtst_Theatrs.Tables[0].Rows[i]["Record_Id"].ToString();
lst_Date_Check.Add(obj_Date_Check);
}
}
Here is my Date_Check object :
public class Date_Check
{
public string Record_Id { get; set; }
public string Movie_Name { get; set; }
}
When dataset iteration is completed the lst_Date_Check got all the indexes changed to the Last iterations values ,what's wrong with my code
Keep creation of the object of the class Date_Check obj_Date_Check = new Date_Check(); inside the for-loop. That's how you make new object on every iteration.
for (int i = 0; dtst_Theatrs.Tables[0].Rows.Count > i; i++)
{
Date_Check obj_Date_Check = new Date_Check();
obj_Date_Check.Movie_Name = dtst_Theatrs.Tables[0].Rows[i]["Movie_Name"].ToString();
obj_Date_Check.Record_Id = dtst_Theatrs.Tables[0].Rows[i]["Record_Id"].ToString();
lst_Date_Check.Add(obj_Date_Check);
}
This is because your Date_Check object is a reference type and not a value type. This means the line Date_Check obj_Date_Check = new Date_Check(); creates the variable in memory once and from then on every time update that object you are updating the same single object. You have 2 options:
Instantiate the object inside the for loop to create a single object in memory to work with i.e:
for (int i = 0; dtst_Theatrs.Tables[0].Rows.Count > i; i++)
{
Date_Check obj_Date_Check = new Date_Check();
obj_Date_Check.Movie_Name = dtst_Theatrs.Tables[0].Rows[i]["Movie_Name"].ToString();
obj_Date_Check.Record_Id = dtst_Theatrs.Tables[0].Rows[i]["Record_Id"].ToString();
lst_Date_Check.Add(obj_Date_Check);
}
Or create your Date_Check object as a Value Type by using a Struct i.e:
public struct Date_Check
{
public string Record_Id { get; set; }
public string Movie_Name { get; set; }
}

Get string value and add to specific variables

I want to get the value in an array and i want to put it in a variable
This is the array {1,eli}
CsvValues = RowData.Split(new string[] {","},
StringSplitOptions.RemoveEmptyEntries); // RowData is {1,eli}
List<string> elements = new List<string>();
foreach (string data in CsvValues)
{
elements.Add(data);
}
and then I want to put it here:
result.Add(new wsSample()
{
id = elements[0],
name = elements[1]
});
How will i add the elements value to id and name?
public class wsSample
{
[DataMember]
public string id { get; set; }
[DataMember]
public string name { get; set; }
}
How is the rest of the input array structured?
If it is elements = {"1","eli", "2","manning"}
then you might be better off using a for loop.
I think this is what you are looking for
List<wsSample> samples = new List<wsSample>();
for(int i=0; i< elements.length-1; ++i)
{
samples.Add(new wsSample()
{
id = elements[i]
name = elements[i+1]
});
i= i+2;
}

C# Linq "Entity with the same key '0' already added." when inserting multiple rows

I am trying to insert data in bulk, database is MySQL connection is done using Devart LinqConnect.
Here is a code:
DataContext db = new DataContext();
List<XYData> XYDList = new List<XYData>(); // Data Type
List<xydata> xyToBeInsrted = new List<xydata>(); // Database table
XYDList = XYData.genXYData(12, 1234); // Generates 12 example records
foreach (XYData oneXY in XYDList)
{
// Create clear row representation
xydata xy_row = new xydata();
// Assign data from object
xy_row.id = oneXY.Id;
xy_row.Batchid = (int)oneXY.BatchId;
xy_row.Ch = oneXY.Channel;
xy_row.Value = oneXY.Value;
xy_row.Pos = (int)oneXY.Position;
xy_row.Dtm = oneXY.Time;
// Add to list of rows to be inserted
xyToBeInsrted.Add(xy_row);
}
db.xydatas.InsertAllOnSubmit<xydata>(xyToBeInsrted);
db.SubmitChanges();
Last line gives an error "Entity with the same key '0' already added."
When I lower number of items to be generated to 1 then it works. Anything above 1 gives error.
Table has set Auto Increment on record Id field.
Trying to solve that for 2 hours without success.
EDIT:
Data Class:
public class XYData
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int Id { get; set; }
public int BatchId { get; set; }
public int Channel { get; set; }
public String Value { get; set; }
public double Position { get; set; }
public DateTime Time { get; set; }
private static Random rand = new Random();
public XYData(int channel = 0, string val = "")
{
Channel = channel;
Value = val;
Position = 0;
Time = DateTime.Now;
}
public static List<XYData> genXYData(int howMany, int batchId)
{
List<XYData> _allXYData = new List<XYData>();
for (int i = 0; i < howMany; i++)
{
XYData _singleXY = new XYData();
_singleXY.BatchId = batchId;
for (int j = 64 * (1 << i); j > 0; j--)
{
uint k = (uint)rand.Next(int.MaxValue);
_singleXY.Value += k.ToString("X8");
}
_allXYData.Add(_singleXY); // Add to list
}
return _allXYData; // Return list of generated data.
}
}
Something like this may be needed on your model definition -
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public int Id { get; set; }
http://www.devart.com/linqconnect/docs/PrimaryKeyMapping.html

Categories

Resources