How to use PagedDataSource CopyTo()? - c#

I get an error when ReadInDataFromRssAndReturnArrayWithTheDataStatic is called because that the DataSource can't be stored in the array specified in the CopyTo-method.
I wonder how I should find which array-type that I should use.
Here follows some of my code:
public static class StillingslisteStatic
{
public static string RssSourceStatic { get; set; }
public static string StillingssideStatic { get; set; }
//This contains all of the data from the rss-file!!
public static PagedDataSource PgdsPositionsStatic { get; set; }
//This function is written by Anders Branderud
public static DataView[] ReadInDataFromRssAndReturnArrayWithTheDataStatic(PageData ledigeStillingerPage)
{
DataView[] myObjArray = null; //I also tried with DataTable
if (ledigeStillingerPage["Stillingsside"] != null)
StillingssideStatic = ledigeStillingerPage["Stillingsside"].ToString();
if (ledigeStillingerPage["RssSource"] != null) RssSourceStatic = (string)ledigeStillingerPage["RssSource"];
if (!string.IsNullOrEmpty(RssSourceStatic))
{
FilterTableStatic(LoadFeedStatic(RssSourceStatic, ledigeStillingerPage), 100); //This initializes PgdsPositionsStatic
myObjArray = new DataView[PgdsPositionsStatic.Count]; //one DataTable is one item
PgdsPositionsStatic.CopyTo(myObjArray, 0);
}
return myObjArray;
}
private static DataTable LoadFeedStatic(string url, PageData ledigeStillingerPage)
{
var reader = new XmlTextReader(url);
var ds = new DataSet();
ds.ReadXml(reader);
foreach (DataTable table in ds.Tables)
{
if (table.TableName == "item")
{
return table;
}
}
return null;
}
private static void FilterTableStatic(DataTable table2Filter, int count)
{
PgdsPositionsStatic = new PagedDataSource();
if (table2Filter == null) return;
int counter = 1;
var deleteItems = new DataRow[table2Filter.Rows.Count];
foreach (DataRow row in table2Filter.Rows)
{
if (counter > count)
deleteItems[counter - count] = row; ;
counter++;
}
for (int i = 0; i < (counter - count); i++)
{
var row = (DataRow)deleteItems[i];
if (row == null)
continue;
table2Filter.Rows.Remove(row);
}
PgdsPositionsStatic.DataSource = table2Filter.DefaultView;
}
Error message:
{"Message":"Object cannot be stored in an array of this type.","StackTrace":" at System.Array.InternalSetValue(Void* target, Object value)\r\n at System.Array.SetValue(Object value, Int32 index)\r\n at System.Web.UI.WebControls.PagedDataSource.CopyTo(Array array, Int32 index)\r\n at

Related

pass a class instance from a list of instances to SQL database and bind it to a gui datagrid

im trying to create a library managment system where the manager can add books or games thru the gui, im struggeling to find a way to pass the class instance to the database while keep the datagrid that shows the avalible items in the library updated.
what is the best way to do it ?
first create a class instance and then pass a list of the items to the database?
or when the new item is created, immidiatlly add it to the database and then assign the list to get items from the database, and assign the datagrid to get data from the list? if so how can i convert variables from database into an class instance?
i have created a local host database in my computer.
need to say that i have just learned sql and real amateur in it, and i did manage to get the datagrid to get the data from the database but it still empty so my main problem is how can i fill it according to the class properties and get it updated when a new item is added.
managing class
namespace TheLastLibrary.Classes
{
public class MainLibrary
{
public List<Item> Items = new List<Item>();
SqlService DbService;
public MainLibrary()
{
//DbService = new SqlService();
//DbService.SqlQuery("SELECT * FROM LibraryTable");
//DbService._connection.Open();
//DbService._reader = DbService._cmd.ExecuteReader();
//DbService._dataTable.Load(DbService._reader);
//DbService._connection.Close();
}
public void AddBook(string name, string description, double price, int discount, int minimumAge, int quantity, BooksGenres b, string author)
{
Items.Add(new Book(name, description, price, discount, minimumAge, quantity, b, author));
BookToDb(name);
}
public void AddGame(string name, string description, double price, int discount, int minimumAge, int quantity, GamesGenres g)
{
Items.Add(new Game(name, description, price, discount, minimumAge, quantity, g));
}
public List<Item> GetItems()
{
return Items;
}
void UpdateName(Item i, string NewName)
{
i.Name = NewName;
}
void UpdatePrice(Item i, double NewPrice)
{
i.Price = NewPrice;
}
void UpdateDiscount(Item i, int NewDiscount)
{
i.Discount = NewDiscount;
}
void UpdateQuantity(Item i, int NewQuantity)
{
i.Quantity = NewQuantity;
}
Item SearchByName(string name)
{
foreach (Item i in Items)
{
if (i == null) throw new ArgumentNullException();
if (i.Name == name) return i;
}
return null;
}
Item SearchById(int id)
{
foreach (Item i in Items)
{
if (i == null) throw new ArgumentNullException();
if (i.Id == id) return i;
}
return null;
}
Item SearchByPriceRange(int min, int max)
{
foreach (Item i in Items)
{
if (i == null) throw new ArgumentNullException();
if (i.Price <= max && i.Price >= min) return i;
}
return null;
}
Item SearchByMinimumAge(int min)
{
foreach (Item i in Items)
{
if (i == null) throw new ArgumentNullException();
if (i.MinimumAge <= min && i.Price >= min) return i;
}
return null;
}
Item SearchByGenre(string genre)
{
foreach (Item i in Items)
{
if (i == null) throw new ArgumentNullException();
if (i.Genre == genre) return i;
}
return null;
}
public void BookToDb(string name)
{
Book B = (Book)SearchByName(name);
foreach (PropertyInfo prop in typeof(Book).GetProperties())
{
foreach(DataColumn Dc in DbService._dataTable.Columns)
{
if (Dc.ColumnName == prop.Name)
{
DbService._connection.Open();
DbService.SqlQuery($"INSERT INTO LibraryTable ({Dc.ColumnName}) VALUES {prop.GetValue(B)}");
DbService._connection.Close();
}
}
}
}
trying to pass instance to data base according to properties , without sucess
}
sql service
internal class SqlService
{
public SqlConnection _connection { get;}
public SqlCommand _cmd;
private SqlDataAdapter _adapter;
public SqlDataReader _reader { get; set; }
public DataTable _dataTable { get; set; }
public SqlService()
{
_connection = new SqlConnection(#"Data Source=DESKTOP-9BRI5GA;Initial Catalog=LibraryDb;Integrated Security=True");
SqlQuery("SELECT * FROM LibraryTable");
_connection.Open();
_reader = _cmd.ExecuteReader();
_dataTable.Load(_reader);
_connection.Close();
}
public void SqlQuery(string QueryText)
{
_cmd = new SqlCommand(QueryText, _connection);
}
public DataTable QueryEx()
{
_adapter = new SqlDataAdapter(_cmd);
_dataTable = new DataTable();
_adapter.Fill(_dataTable);
return _dataTable;
}
public void NonQueryEx()
{
_cmd.ExecuteNonQuery();
}
//public bool InsertBulkRecords<T>(List<T> records)
//{
// bool Inserted = false;
// return Inserted;
//}
//public DataTable GetTable<T>(List<T> records)
//{
// var type = typeof(T);
// return _dataTable;
//}
}
}

How to apply Linq to Observable Collection of Generic Property?

How to apply the linq concept to Generic property Collection. I have converted the Data Table to Collection as like Converter
I have the DataTable and then convert it to Collection as like
class Program
{
static void Main(string[] args)
{
DataTable dtResult = new DataTable();
dtResult.Columns.Add("ID", typeof(int));
dtResult.Columns.Add("Name", typeof(string));
DataRow dtRow = dtResult.NewRow();
dtRow["ID"] = 1;
dtRow["Name"] = "Bala";
dtResult.Rows.Add(dtRow);
dtRow = dtResult.NewRow();
dtRow["ID"] = 2;
dtRow["Name"] = "Bala1";
dtResult.Rows.Add(dtRow);
var Collection = Convert(dtResult);
// var property = Collection.Where(a=>a.Properties.Where(x => (x as GenericProperty).Name.Equals("ID") && (x as GenericProperty).Value.Equals(1));
// I would like to get the ID matching 2 Record How to get this using linq query
}
private static ObservableCollection<GenericObject> Convert(DataTable toConvert)
{
ObservableCollection<GenericObject> _result = new ObservableCollection<GenericObject>();
foreach (DataRow _row in toConvert.Rows)
{
GenericObject _genericObject = new GenericObject();
foreach (DataColumn _column in toConvert.Columns)
{
_genericObject.Properties.Add(new GenericProperty(_column.ColumnName, _row[_column]));
}
_result.Add(_genericObject);
}
return _result;
}
}
public class GenericObject
{
private readonly ObservableCollection<GenericProperty> properties = new ObservableCollection<GenericProperty>();
public GenericObject(params GenericProperty[] properties)
{
foreach (var property in properties)
Properties.Add(property);
}
public ObservableCollection<GenericProperty> Properties
{
get { return properties; }
}
}
public class GenericProperty : INotifyPropertyChanged
{
public GenericProperty(string name, object value)
{
Name = name;
Value = value;
}
public string Name { get; private set; }
public object Value { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
Now my question is to how can i apply the linq concept to get the MAtched Record??
Is this what you want?
var property =
from a in Collection
where a.Properties.Any(p => p.Name == "ID" && (int)p.Value == 1)
select a;
That gives:

Memory exception HashSet

I get an memory exception while loading a 4GB file. i have to do that twice but i have enougth memmory to load them. the memmory exception occures when i have 3gb left or more.:(.
Method:
public TableModel LoadTable(string path) {
TableModel model = new TableModel();
using (FileStream filestream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
using (StreamReader reader = new StreamReader(filestream, Encoding.UTF8)) {
string line = "";
bool isHeader = true;
int counter = 0;
List<string> rows = new List<string>();
while ((line = reader.ReadLine()) != null) {
if (isHeader) {
model.Columns = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
isHeader = false;
continue;
} else {
if (Settings.Default.RonudSet != 0) {
rows.Add(RoundDecimals(line));
} else {
rows.Add(line);
}
}
counter++;
}
model.RowCount = counter;
model.ColumnsCount = model.Columns.Length;
model.Keys = new HashSet<string>(rows);
}
}
return model;
}
Exception:
System.OutOfMemoryException was unhandled
The function evaluation was disabled because of an out of memory exception.
TableModel:
class TableModel {
private string tableName;
private string[] columns;
private HashSet<string> keys;
public int ColumnsCount { get; set; }
public int RowCount { get; set; }
public string TableName { get { return tableName; } set { this.tableName = value; } }
public string[] Columns { get { return columns; } set { this.columns = value; } }
public HashSet<string> Keys { get { return keys; } set { this.keys = value; } }
}
Start Compare:
if (newFile.Name.Equals(currFile.Name)) {
FileLoader loader = new FileLoader();
TableModel newModel = loader.LoadTable(newFile.ToString());
TableModel currentModel = loader.LoadTable(currFile.ToString());
newModel.TableName = newFile.Name;
currentModel.TableName = currFile.Name;
new Compare(newModel, currentModel, currFile.Directory.Name);
break;
}
Compare:
private void CheckColumns() {
bool sameColumnCount = CheckColumnsCount();
int counter = 0;
currentContent = new HashSet<string>(currentModel.Columns);
newContent = new HashSet<string>(newModel.Columns);
foreach (string header in currentContent) {
if (!newContent.Contains(header)) {
headersNotFoundInN.Add(header);
}
}
foreach (string header in newContent) {
if (!currentContent.Contains(header)) {
headersNotFoundInC.Add(header);
}
}
if (currentModel.ColumnsCount == newModel.ColumnsCount) {
for (int i = 0; i < currentModel.ColumnsCount; i++) {
if (currentModel.Columns[i] == newModel.Columns[i]) {
counter++;
}
}
if (counter == currentModel.ColumnsCount) {
headerSequence = true;
} else {
headerSequence = false;
}
} else {
headerSequence = false;
}
bool emptyNotFoundIn = false;
if (headersNotFoundInC.Count == 0 && headersNotFoundInN.Count == 0) {
emptyNotFoundIn = true;
}
ReportContent(sameColumnCount, headerSequence, emptyNotFoundIn);
}
private void CheckRows() {
bool sameRowCount = CheckRowCount();
currentContent = new HashSet<string>(currentModel.Keys);
newContent = new HashSet<string>(newModel.Keys);
foreach (string key in currentContent) {
if (!newContent.Contains(key)) {
rowNotFoundInN.Add(key);
}
}
foreach (string key in newContent) {
if (!currentContent.Contains(key)) {
rowNotFoundInC.Add(key);
}
}
bool emptyNotFoundIn = false;
if (rowNotFoundInC.Count == 0 && rowNotFoundInN.Count == 0) {
emptyNotFoundIn = true;
}
ReportContent(sameRowCount, emptyNotFoundIn);
}
Its a table with many rows that i have to compare with a similar table. at the end i have to give a report about the diffrences. but i fail here where i have to load this massive file.
try using BufferedStream
using (BufferedStream bs = new BufferedStream(filestream))
{
}

Get multiple items in one session

I am storing multiple items into one session variable: which is 4 different words.
I need to be able to take those 4 different wordsin the one session, and store them into separate variables so i can use them, is this possible? and if so how?
_application just holds text from a series of text from text boxes.
Here is my session class.
public class JobApplicantSession
{
public JobApplication ApplicationSession
{
get {if (HttpContext.Current.Session["Application"] != null)
return (JobApplication)HttpContext.Current.Session["Application"];
return null; }
set{ HttpContext.Current.Session["Application"] = value; }
}
Job application: Job application holds information from a list of textboxes thats it.
JobApplication _application;
_application = new JobApplication(jobID);
if (i < _applicant.Fields.Count)
_applicant.AddAnswer((_controlsList[i] as TextBox).Text);
else
_application.AddAnswer((_controlsList[i] as TextBox).Text);
add to the session:
_sessions.ApplicationSession = _application;
I can get the session:
JobApplication application;
var jas = new JobApplicantSession();
application = jas.ApplicationSession;
Job application:
public class JobApplication
{
private int _jobID = -1;
public JobApplication(int jobID)
{
_jobID = jobID;
}
List<String> _answers = new List<String>();
List<JobApplicationField> _fields = new List<JobApplicationField>();
public List<JobApplicationField> Fields
{
get { return _fields; }
}
public int JobID()
{
return _jobID;
}
public List<String> Answers
{
get { return _answers; }
set { _answers = value; }
}
public void AddAnswer(String answer)
{
_answers.Add(answer);
}
public void AddField(JobApplicationField field)
{
if (field.HasFieldID)
{
for (int i = 0; i < _fields.Count(); i++)
{
if (_fields[i].FieldID == field.FieldID)
{
_fields[i] = field;
return;
}
}
}
_fields.Add(field);
}
public void PopulateFromDatabase()
{
JobPositionSystemDAL dal = new JobPositionSystemDAL();
DataSet data = dal.OpenJobOpeningByID(_jobID);
foreach (DataRow row in data.Tables[0].Rows)
{
JobApplicationField field = new JobApplicationField(Convert.ToInt32(row["QUESTIONID"]), row["QUESTIONTEXT"].ToString(), Convert.ToBoolean(row["HASCORRECTANSWER"]), row["CORRECTANSWER"].ToString(), Convert.ToBoolean(row["ISREQUIRED"]));
AddField(field);
}
}
public bool Verify()
{
if (_fields.Count != Answers.Count)
throw new Exception("Number of answers != number of fields");
for (int i = 0; i < _fields.Count; i++)
{
if (_fields[i].HasCorrectAnswer == true && _fields[i].CorrectAnswer != _answers[i])
return false;
}
return true;
}
public void Save()
{
JobPositionSystemDAL database = new JobPositionSystemDAL();
foreach(JobApplicationField field in _fields)
{
field.Save(_jobID, ref database);
}
//reload to get the Field/question ID for any new fields
Reload();
}
public void Reload()
{
_fields = new List<JobApplicationField>();
Load(_jobID);
}
public void Load(int jobID)
{
_jobID = jobID;
DataSet ds = DB.OpenJobOpeningByID(jobID);
DataTable table = ds.Tables[0];
foreach (DataRow row in table.Rows)
{
int questionID = 0;
object obj = row["QUESTIONID"];
Int32.TryParse(obj.ToString(), out questionID);
//int jobApplicationID = Int32.Parse(row["JOBAPPLICATIONID"] as String);
string questionText = row["QUESTIONTEXT"] as String;
int type = Int32.Parse(row["TYPEID"].ToString());
bool hasCorrectAnswer = (row["HASCORRECTANSWER"] as String == "0") ? false : true;
string correctAnswer = row["CORRECTANSWER"] as String;
bool required = ((row["ISREQUIRED"] as String) == "0") ? false : true;
JobApplicationField field = new JobApplicationField(questionID, questionText, hasCorrectAnswer, correctAnswer, required);
AddField(field);
}
}
private JobPositionSystemDAL _db;
private JobPositionSystemDAL DB
{
get
{
if (null == _db)
_db = new JobPositionSystemDAL();
return _db;
}
}
}
}
How can i loop through and store each item into its own variable?
i will need 4 variables.
Hope it is what you are asking. If you want to store array of objects in session state you can either sotre array directly:
HttpContext.Current.Session["data"] = new int[32];
or dynamically create names based on element index (strange, but possible):
var data = new int[3];
HttpContext.Current.Session["data" + 0.ToString()] = data[0];
HttpContext.Current.Session["data" + 1.ToString()] = data[1];
HttpContext.Current.Session["data" + 2.ToString()] = data[2];
Read in reverse order:
var dataArray = (int[])(HttpContext.Current.Session["data"]);
or
var data = new int[3];
data[0] = (int)HttpContext.Current.Session["data" + + 0.ToString()];

How to sort databound DataGridView column?

I know that there are a lot of questions on this topic. I have been through all of them but nothing seems to help.
How to sort by clicking on column header?
How should I modify this code to do the job?
public partial class Form1 : Form
{
public Form1()
{
List<MyClass> list = new List<MyClass>();
list.Add(new MyClass("Peter", 1202));
list.Add(new MyClass("James", 292));
list.Add(new MyClass("Bond", 23));
BindingSource bs = new BindingSource();
bs.DataSource = list;
DataGridView dg = new DataGridView();
DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn();
c.Name = "name";
c.DataPropertyName = "Name";
dg.Columns.Add(c);
c = new DataGridViewTextBoxColumn();
c.Name = "number";
c.DataPropertyName = "Number";
dg.Columns.Add(c);
dg.DataSource = bs;
this.Controls.Add((Control)dg);
}
}
class MyClass:IComparable<MyClass>
{
public string Name { get; set; }
public int Number { get; set; }
public MyClass(){}
public MyClass(string name,int number)
{
Name = name;
Number = number;
}
public override string ToString()
{
return string.Format("{0}:{1}",Name,Number);
}
#region IComparable<MyClass> Members
public int CompareTo(MyClass other)
{
return Name.CompareTo(other.Name);
}
#endregion
}
I recall having issues finding something that would work when I added sorting to my datagrids too. You can implement a sortable bindable list by first adding the following class to your project. It is a list implementation that implements BindingList<T>, so that you can bind your datagrid to it, and it also supports sorting. A better explanation of the details than I could give is on MSDN here
public class SortableBindingList<T> : BindingList<T>
{
private ArrayList sortedList;
private ArrayList unsortedItems;
private bool isSortedValue;
public SortableBindingList()
{
}
public SortableBindingList(IList<T> list)
{
foreach (object o in list)
{
this.Add((T)o);
}
}
protected override bool SupportsSearchingCore
{
get
{
return true;
}
}
protected override int FindCore(PropertyDescriptor prop, object key)
{
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;
if (key != null)
{
for (int i = 0; i < Count; ++i)
{
item = (T)Items[i];
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}
public int Find(string property, object key)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
PropertyDescriptor prop = properties.Find(property, true);
if (prop == null)
return -1;
else
return FindCore(prop, key);
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return isSortedValue; }
}
ListSortDirection sortDirectionValue;
PropertyDescriptor sortPropertyValue;
protected override void ApplySortCore(PropertyDescriptor prop,
ListSortDirection direction)
{
sortedList = new ArrayList();
Type interfaceType = prop.PropertyType.GetInterface("IComparable");
if (interfaceType == null && prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
if (underlyingType != null)
{
interfaceType = underlyingType.GetInterface("IComparable");
}
}
if (interfaceType != null)
{
sortPropertyValue = prop;
sortDirectionValue = direction;
IEnumerable<T> query = base.Items;
if (direction == ListSortDirection.Ascending)
{
query = query.OrderBy(i => prop.GetValue(i));
}
else
{
query = query.OrderByDescending(i => prop.GetValue(i));
}
int newIndex = 0;
foreach (object item in query)
{
this.Items[newIndex] = (T)item;
newIndex++;
}
isSortedValue = true;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
else
{
throw new NotSupportedException("Cannot sort by " + prop.Name +
". This" + prop.PropertyType.ToString() +
" does not implement IComparable");
}
}
protected override void RemoveSortCore()
{
int position;
object temp;
if (unsortedItems != null)
{
for (int i = 0; i < unsortedItems.Count; )
{
position = this.Find("LastName",
unsortedItems[i].GetType().
GetProperty("LastName").GetValue(unsortedItems[i], null));
if (position > 0 && position != i)
{
temp = this[i];
this[i] = this[position];
this[position] = (T)temp;
i++;
}
else if (position == i)
i++;
else
unsortedItems.RemoveAt(i);
}
isSortedValue = false;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}
public void RemoveSort()
{
RemoveSortCore();
}
protected override PropertyDescriptor SortPropertyCore
{
get { return sortPropertyValue; }
}
protected override ListSortDirection SortDirectionCore
{
get { return sortDirectionValue; }
}
}
With that in place, the only changes you need to make to the code that you have posted above is to create a SortableBindingList based on your list and bind to the sortable list, rather than the standard one, like so:
List<MyClass> list = new List<MyClass>();
list.Add(new MyClass("Peter", 1202));
list.Add(new MyClass("James", 292));
list.Add(new MyClass("Bond", 23));
// Added sortable list...
SortableBindingList<MyClass> sortableList = new SortableBindingList<MyClass>(list);
BindingSource bs = new BindingSource();
bs.DataSource = sortableList; // Bind to the sortable list
And that will be enough to get you going.
Here is the blog post that really really helped me.
Presenting the SortableBindableList
Also, check out How do I implement automatic sorting of DataGridView? which has examples of this and another library.

Categories

Resources