why does an error in list<> in C#? - c#

i am new to class/object.I am getting this error. I don't know why this is not navigating to the desired page. There is my code. Thanks for helping~~
WebService1.asmx.cs
public class yearList
{
public yearList(){}
public int year;
public List<int> list;
public List<int> List()
{
for (int i = -2; i < 3; i++)
{
list.Add(year+i);
}
return list;
}
}
[WebMethod]
public List<int> List()
{
yearList yl = new yearList();
string connStr2 = ConfigurationManager.ConnectionStrings["taisangrent_sql"].ConnectionString;
SqlConnection conn2 = new SqlConnection(connStr2);
string strSQL2 = "select YEAR(getdate()) as year";
SqlDataAdapter adapter2 = new SqlDataAdapter(strSQL2, conn2);
DataSet ds2 = new DataSet();
adapter2.Fill(ds2, "y_m");
yl.year = int.Parse(ds2.Tables["y_m"].Rows[0]["year"].ToString());
return yl.List();
}

try changing..
public List<int> list;
to
public List<int> list = new List<int>();
When you're calling list.Add(year);, the list object has now yet been newed up, so that's why you're getting the error.
I think it would be better to change the method name too...
public List<int> GetList() instead of public List<int> List();
EDIT: Good point by #Hassan
just to clarify, the DataAdapter.Fill() will Open/Close connections automatically.
One of the great features of ADO.NET is that the DataAdapter object's
Fill and Update methods can open and close a connection automatically.
The advantage of this is that it is not necessary to open the
connection explicitly because the DataAdapter opens it for you at the
moment right before it executes its SQL command against the database
and then closes it right afterwards.

When declaring as
public List<int> list;
your object is just creating, it wont assign the memory to it. So just decalre it like
public List<int> list = new List<int>();
And also try to give some other name to your function if its not a constructor as it already a class name.

Related

Recursive method call results in StackOverflow exception

Having written this question out, and created a MCVE, it sounds a bit like homework, but really it isn't...
I'm unfortunately too old to be set homework.
I'm trying to write a small app to populate a database I'm working on with a 'pyramid' structure.
There's one original member, who refers 10 members.
Each of these referrals can have 10 referrals. Each of those, has 10 referrals. And so on...
I'm trying to fill the database with a maximum number of members (which is supplied)
If I set the maximum number of members to 100,000 - this works.
200,000 however, throws a StackOverflow exception.
I'm pretty sure it's down to me not terminating the 'fanning out' early enough. But I can't for the life of me figure out where.
Note, my MCVE below is using Dapper for simplicity sake, hence the simple INSERT INTO statement
public class MemberPopulator
{
private readonly SqlConnection connection;
private const string MemberSql = #"
INSERT INTO Members (FirstName, LastName, ReferralId, Active, Created)
VALUES (#FirstName, #LastName, #ReferralId, #Active, #Created);
SELECT CAST(SCOPE_IDENTITY() as int)";
private int TotalMemberCount;
private const int MaxMemberCount = 200000;
public MemberPopulator()
{
connection = new SqlConnection("Data Source=localhost;Initial Catalog=MyTestDb;Integrated Security=True");
}
public void CreateMembers()
{
//clear members
connection.Execute("TRUNCATE TABLE Members");
//create the 'original' member (top of pyramid)
var originalMemberId = connection.Query<int>(MemberSql, new Member
{
FirstName = "FirstName Goes Here",
ReferralId = 0
}).Single();
//now we have 1 total members
TotalMemberCount = 1;
//recursively create members, starting with original member,
RecursiveCreate(new[] { originalMemberId });
}
private void RecursiveCreate(IEnumerable<int> referralMemberIds)
{
//don't recurse if we've already got enough members
if (TotalMemberCount >= MaxMemberCount)
return;
foreach (var referralId in referralMemberIds)
{
//Create 10 members
var refs = CreateReferredMembers(referralId, 10);
RecursiveCreate(refs);
}
}
private IEnumerable<int> CreateReferredMembers(int referralId, int numberOfReferrals)
{
var referredMemberIds = new List<int>();
for (var i = 0; i < numberOfReferrals; i++)
{
if (TotalMemberCount >= MaxMemberCount)
break;
var member = new Member
{
FirstName = "FirstName Goes Here",
ReferralId = referralId
};
var memberId = connection.Query<int>(MemberSql, member).Single();
referredMemberIds.Add(memberId);
TotalMemberCount++;
}
return referredMemberIds;
}
}
The stack in C# is set to 1MB for 32bit applications or 4MB for 64bit applications by default. This is suitable for most applications. In case you need more please follow the guidance in the net (for example this one).
In case you do not know exactly the level of recursion I would suggest to simulate recursion by using a Stack or Queue datatype.
public class MemberPopulator
{
private readonly SqlConnection connection;
private const string MemberSql = #"
INSERT INTO Members (FirstName, LastName, ReferralId, Active, Created)
VALUES (#FirstName, #LastName, #ReferralId, #Active, #Created);
SELECT CAST(SCOPE_IDENTITY() as int)";
private int TotalMemberCount;
private const int MaxMemberCount = 200000;
public MemberPopulator()
{
connection = new SqlConnection("Data Source=localhost;Initial Catalog=MyTestDb;Integrated Security=True");
}
public void CreateMembers()
{
//clear members
connection.Execute("TRUNCATE TABLE Members");
//create the 'original' member (top of pyramid)
var originalMemberId = connection.Query<int>(MemberSql, new Member
{
FirstName = "FirstName Goes Here",
ReferralId = 0
}).Single();
//now we have 1 total members
TotalMemberCount = 1;
//recursively create members, starting with original member,
NonRecursiveCreate(originalMemberId);
}
private void NonRecursiveCreate(int root)
{
Queue<int> members = new Queue<int>();
members.Enqueue(root);
while (members.Any() && TotalMemberCount < MaxMemberCount)
{
var referralId = members.Dequeue();
//Create 10 members
var refs = CreateReferredMembers(referralId, 10);
foreach (int i in refs)
{
members.Enqueue(i);
}
}
}
private IEnumerable<int> CreateReferredMembers(int referralId, int numberOfReferrals)
{
var referredMemberIds = new List<int>();
for (var i = 0; i < numberOfReferrals; i++)
{
if (TotalMemberCount >= MaxMemberCount)
break;
var member = new Member
{
FirstName = "FirstName Goes Here",
ReferralId = referralId
};
var memberId = connection.Query<int>(MemberSql, member).Single();
referredMemberIds.Add(memberId);
TotalMemberCount++;
}
return referredMemberIds;
}
}

foreach statement cannot operate on variables of type 'gerant' because 'gerant' does not contain a public definition for 'GetEnumerator'

hello i try to create an object named 'gerant'
class gerant
{
public double CIN_GERANT, NUM_TEL_GERANT, MOBILE_GERANT;
public string NOM_GERANT, PRENOM_GERANT, ADRESSE__GERANT, MAIL_GERANT, VILLE_GERANT;
public int CP_GERANT;
public DateTime DATE_GERANT;
public gerant(double _Cin_gerant, string _Nom_Gerant, string _Prenom_Gerant, string _Adresse_Gerant, double _Num_Tel_Gerant, string _Mail_Gerant, double _Mobile_Gerant, int _cp_gerant, string _ville_gerant, DateTime _date_gerant)
{
this.CIN_GERANT = _Cin_gerant;
this.NOM_GERANT = _Nom_Gerant;
this.PRENOM_GERANT = _Prenom_Gerant;
this.ADRESSE__GERANT = _Adresse_Gerant;
this.NUM_TEL_GERANT = _Num_Tel_Gerant;
this.MAIL_GERANT = _Mail_Gerant;
this.MOBILE_GERANT = _Mobile_Gerant;
this.CP_GERANT = _cp_gerant;
this.VILLE_GERANT = _ville_gerant;
this.DATE_GERANT = _date_gerant;
}
public gerant getinfogerant()
{
gerant gerer = null;
string sql_gerant = "select CIN,NOM,PRENOM,ADRESS_PERSONNEL,NUM_TEL,MAIL,MOBILE,CP_GERANT,VILLE_GERANT,DATE_CIN from GERANT";
connexion connect = new connexion();
OleDbConnection connection = connect.getconnexion();
// try
//{
connection.Open();
OleDbCommand cmd = new OleDbCommand(sql_gerant, connection);
OleDbDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
gerer = new gerant(reader.GetDouble(0),
reader.GetString(1),
reader.GetString(2),
reader.GetString(3),
reader.GetDouble(4),
reader.GetString(5),
reader.GetDouble(6),
reader.GetInt32(7),
reader.GetString(8),
reader.GetDateTime(9)
);
}
connection.Close();
return gerer;
}
}
but when i try to fill my combobox with gerant i try to insert this code
foreach(Modele.gerant ligne in liste_gerant)
{
}
but i make this error for me
foreach statement cannot operate on variables of type 'gerant' because 'gerant' does not contain a public definition for 'GetEnumerator'
how can i resolve that?
Based on your comments. The gerant class is not a collection of any sort, and your getinfogerant doesn't return a collection.
So, the problem is that you are trying to iterate over a single value.
From the query You use in getinfogerant I guess you want it to get all "gerant" in your db, not just one?
However now you're just returning the first. You should change its return type to List and turn the if (reader.Read()) into a while loop to fill the list, then return the whole list at the end.

How to retrieve specific set of values from the array of objects using linq

I have one class as below:
public class test
{
int i;
string str;
Socket s;
DateTime dt;
}
and am creating object of this class as below
public void collection()
{
test t1=new test{i=1,str="string1", s=soc1, dt=DateTime.Today() };
test t2=new test{i=2,str="string2", s=soc2, dt=DateTime.Today() };
test t3=new test{i=3,str="string3", s=soc3, dt=DateTime.Today() };
ArraList a=new ArrayList();
a.Add(t1);
a.Add(t2);
a.Add(t3);
}
and am adding all these objects(t1,t2,t3) into an array. Now, how can i get all socket members in object array using linq???
You should use Generic List instead of ArrayList, if you are working on .Net framework 2.0 or above. (You have to define your fields as public to be accessible outside the class)
List<test> list = new List<test>();
list.Add(t1);
....
To get all items you can do:
var items = list.Select(r=> r.s).ToArray();
There are many other problems in your code. DateTime.Today is used like a method, whereas its just a property. If you want to use ArrayList then your classes and corrected code should be:
public class test
{
public int i;
public string str;
public Socket s;
public DateTime dt;
}
test t1 = new test { i = 1, str = "string1", s = soc1, dt = DateTime.Today };
test t2 = new test { i = 2, str = "string2", s = soc2, dt = DateTime.Today };
test t3 = new test { i = 3, str = "string3", s = soc3, dt = DateTime.Today };
ArrayList a = new ArrayList();
a.Add(t1);
a.Add(t2);
a.Add(t3);
To select sockets from the ArrayList
var items = a.Cast<test>().Select(r=> r.s).ToArray();
I think you should cast your ArrayList to a collection of type 'test'
so
a.Cast<test>.Select(t => t.s);
Will give you the result.
Or if you think your ArrayList might also contain other types of obejct, you can use
a.OfType<test>.Select(t => t.s);
Note: Make sure Socket is a publicly accessible property and depending on the framework you use, consider using a Generic collection
You can do it in this way (this requires public properties of test):
var a = new List<test>()
{
new test{i=1,str="string1", s=soc1, dt=DateTime.Today() },
new test{i=2,str="string2", s=soc2, dt=DateTime.Today() },
new test{i=3,str="string3", s=soc3, dt=DateTime.Today() }
};
var sockets = a.Select(t => t.s);

Dataset1 - method connection

I have got problem with this method:
public List<int> menu_wid_w_kat()
{
DataSet1TableAdapters.menu_widac_wszystkoTableAdapter pk = new DataSet1TableAdapters.menu_widac_wszystkoTableAdapter();
List<int> lista = new List<int>();
lista = pk.?
return lista;
}
In dataset1 I have got Fill, GetData (#id) and this is connected with procedure (procedure working correct)
Problem is in this method because I don't know how connect this method with dataset1 (but I don't want to using linq: (lista = (from o in pk.GetData() select o.nazwa).ToList();))
my idea was but does not work but probably you will understand what I want to do it. Connection with method put (id number) and get data list:
lista = pk.GetData(id)
I just want to take data from this procedure which exist in dataset1.
correct but I can`t find method GetIdList()
baza nasza_baza = new baza();
var da = new DataSet1TableAdapters.menu_widac_wszystkoTableAdapter();
List productIDs = da. <- I cant`t find method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DataSet1TableAdapters
{
public partial class menu_widac_wszystkoTableAdapter
{
public List<int> GetIdList(int ids)
{
List<int> list = new List<int>();
System.Data.SqlClient.SqlCommand command = this.CommandCollection(ids);
command.CommandTimeout = command.Connection.ConnectionTimeout;
System.Data.ConnectionState previousConnectionState = command.Connection.State;
try
{
if (((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open))
{
command.Connection.Open();
}
using (System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
list.Add(reader.GetInt32(0));
}
}
}
finally
{
if ((previousConnectionState == System.Data.ConnectionState.Closed))
{
command.Connection.Close();
}
}
return list;
}
private System.Data.SqlClient.SqlCommand CommandCollection(int p)
{
throw new NotImplementedException();
}
}
}
The fastest approach is to extend the autogenerated TableAdapter in your DataSet with a method that returns your ID's as List<int>.
If you want to extend the functionality you can't change the generated classes in the DatesetName.designer.cs/vb (it will be recreated on any change) but the file without designer in its name(create it if it not exists). Then you have to extend the partial TableAdapter-class(in your case menu_widac_wszystkoTableAdapter).
Have a look at following code to see what i mean, i haven't tested it but i hope you take my point:
namespace YourRootNameSpace.DataSet1TableAdapters {
{
public partial class menu_widac_wszystkoTableAdapter
{
public List<int> GetIdList(int categoryID)
{
List<int> list = new List<int>();
System.Data.SqlClient.SqlCommand command = this.CommandCollection[0];
command.CommandTimeout = command.Connection.ConnectionTimeout;
System.Data.ConnectionState previousConnectionState = command.Connection.State;
try {
if (((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)) {
command.Connection.Open();
}
command.Parameters[ "#id" ].Value = categoryID;
using (System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader()) {
while (reader.Read()) {
list.Add(reader.GetInt32(0));
}
}
} finally {
if ((previousConnectionState == System.Data.ConnectionState.Closed)) {
command.Connection.Close();
}
}
return list;
}
}
}
Edit: After i've read your edited question i saw that i've misunderstood your requirement a little bit, but my approach should be perfect anyway. Basically you don't want to get a DataTable but a List<int> with your product_ids.
After you've extended the TableAdapter in the abovementioned way:
var da = new DataSet1TableAdapters.menu_widac_wszystkoTableAdapter();
List<int> productIDs = da.GetIdList();

Casting Linq to IEnumerable <Datarow>

I'm creating winForm app,In that Onbutton click i gather Data Tables from of Two database Mysql and Sqlite database.
I getting Casting error while on casting Linq query to IEnumerable to make fetch query values to DataTable to make display in DataGrid view.
private void button1_Click(object sender, EventArgs e)
{
var obj = new table1TableAdapter(); //Mysql Table Adapter
var obj2 = new Table1TableAdapter(); // Sqlite Table Adapter
var ds = new DataSet();
ds.Tables.Add(obj.GetData());
ds.Tables.Add(obj2.GetData());
var tab1 = ds.Tables[0];
var tab2 = ds.Tables[1];
var query = from o in tab1.AsEnumerable()
join od in tab2.AsEnumerable()
on o.Field<string>("Name") equals od.Field<string>("Name")
select new
{
Name = o.Field<string>("Name"),
Rollno = od.Field<Int64>("rollno"),
Book = o.Field<string>("Book")
};
var q2 = (IEnumerable<DataRow>)query; //Unable to cast object of type <JoinIterator>
DataTable orderTable = q2.CopyToDataTable();
dataGridView1.DataSource = orderTable;
}
Looking at your code, I'd say, why cast it to IEnumerable<DataRow> at all ? Just simply bind the query to your GridView.
dataGridView1.DataSource = query.ToList();
That's because the query object you are returning has no relation to DataRow. query is going to be an IEnumerable<SomeAnonymousType>. How is it expected to convert to DataRow?
You would need to alter your statement to make a DataRow:
select new DataRow(/* Whatever Params */) { /* More Params */ };
Then it's natively an IEnumerable<DataRow> and needs no casting.
Since your query is creating an IEnumerable you wouldn't be able to cast it to a DataRow. I also wouldn't not advise using select new DataRow(/* Whatever Params /) { / More Params */ }; since this would not be a true DataRow object and would be bad practice.
I would handle it this way. Even if this is a small project, there shouldn't be that much code in your Button_Click handler.
First, create a container object, call it a DTO or ViewModel. I suggest the later.
public class BookViewModel
{
public string Name { get; set; }
public Int64 Rollno { get; set; }
public string Book { get; set; }
}
Next, create a new class that will do your SQL queries. This will separate your Data Access logic from your form logic.
public class BookService
{
public IList<BookViewModel> GetBookViewModel()
{
var obj = new table1TableAdapter(); //Mysql Table Adapter
var obj2 = new Table1TableAdapter(); // Sqlite Table Adapter
var ds = new DataSet();
ds.Tables.Add(obj.GetData());
ds.Tables.Add(obj2.GetData());
var tab1 = ds.Tables[0];
var tab2 = ds.Tables[1];
var query = from o in tab1.AsEnumerable()
join od in tab2.AsEnumerable()
on o.Field<string>("Name") equals od.Field<string>("Name")
select new BookViewModel
{
Name = o.Field<string>("Name"),
Rollno = od.Field<Int64>("rollno"),
Book = o.Field<string>("Book")
};
return query.ToList();
}
}
Last, bind the List to your display.
private void button1_Click(object sender, EventArgs e)
{
BookService bookService = new BookService();
dataGridView1.DataSource = bookService.GetBookViewModel();
}
Now when you go back to make changes to your code, you will easily be able to modify your display logic and with out having to read through all of your intermixed code.
Example:
private void button1_Click(object sender, EventArgs e)
{
BookService bookService = new BookService();
IList<BookViewModel> books = bookService.GetBookViewModel();
if (books.Count == 0)
{
Label1.Text = "Sorry no books were found";
}
dataGridView1.DataSource = books;
}
For one thing, you're not going to be able to cast to an IEnumerable because you're query itself is not producing DataRows
select new
{
Name = o.Field<string>("Name"),
Rollno = od.Field<Int64>("rollno"),
Book = o.Field<string>("Book")
};
is creating an anonymous type.
You would have to change this to a DataRow somehow first, and then convert it to an IEnumerable.
I'm using the following statement and this works for me
UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow[] searchrows =
(from a in _wizardStepPreviewDataSet.AllDossierDetailResults
where a.WingsSetNbr == row.WingsSetNbr && !a.BookCode.StartsWith("V")
select a).ToArray<UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow>();

Categories

Resources