Given a collection of data rows, IEnumerable of type DataRow, how can I query the collection so as to compute the Sum all the values in the collection (i.e. all the values of all the columns in all the rows) with the exception of two specific columns? I know only two columns prior to run time and those are the two I want to exclude. All the others I want included in the sum.
There is a extension method which will give me a specific field, e.g. Field<T>("Foo") but what I really need is the ability to say sum all the fields except field X, Y and Z.
You can use more LINQ:
DataColumn[] unwantedColumns = { table.Column1, ... };
var sum = table.Columns.Cast<DataColumn>()
.Except(unwantedColumns)
.Select(c => row.Field<int>(c))
.Sum();
I don't think you can modify the columns a DataRow has. You can modify the columns of a DataTable though.
Related
I`ve modeled six machines. Each of them has a different profile of electricity load. The load profile is provided in a table in AnyLogic. Every machine has an own table storing these values. I iterate trough the values to implement the same in TableFunctions. Now I face the following challenge: How can I make a dynamic reference to the relevant table. I would like to pick a specific table in dependence of a machine indice. How can I define a variable that dynamically refers to the relevant table object?
Thank you for your help!
not sure it is really necessary in your case but here goes:
You can store a reference to a database table to a variable of the following type:
com.mysema.query.sql.RelationalPathBase
When selecting values of double (int, String, etc.) type in a particular column, you may get the column by index calling variable.getColumns().get(index). Then you need to cast it to the corresponding type like below:
List<Double> resultRows = selectFrom(variable).where(
( (com.mysema.query.types.path.NumberPath<Double>) variable.getColumns().get(1) ).eq(2.0))
.list(( (com.mysema.query.types.path.NumberPath<Double>) variable.getColumns().get(1) ));
Are you always going to have a finite number of machines and how is your load profile represented? If you have a finite number of machines, and the load profile is a set of individual values - or indeed as long as you can hold those values in a single field per element - then you can create a single table, e.g. machine_load_profile, where the first column is load_profile_element and holds element IDs and further columns are named machine_0, machine_1, machine_2 etc., holding the values for each load profile element. You can then get the load profile elements for a single machine like this:
List<Double> dblReturnLPEs = main.selectValues(
"SELECT machine_" + oMachine.getIndex()
+ " FROM machine_load_profile"
+ " ORDER BY load_profile_element;"
);
and either iterate that list or convert them into an array:
dblLPEValues = dblReturnLPEs.stream().mapToDouble(Double::doubleValue).toArray();
and iterate that.
Of course you could also use the opposite orientation for your columns and rows as well, using WHERE, I simply had a handy example oriented in this manner.
I m currently creating a chart(data from an external csv file) but I dont know beforehand the number of columns and rows. Could you maybe point me in the right direction as to where I could find some help(or some examples) with this issue?
Thank you
d3.csv can help you here:
d3.csv('myCSVFile.csv', function(data){
//the 'data' argument will be an array of objects, one object for each row so...
var numberOfRows = data.length, // we can easily get the number of rows (excluding the title row)
columns = Object.keys( data[0] ), // then taking the first row object and getting an array of the keys
numberOfCOlumns = columns.length; // allows us to get the number of columns
});
Note that this method assumes that the first row (and only the first row) of your spreadsheet is column titles.
In addition to Tom P's advice, it's worth noting that version 4 of D3 introduced a columns property, which you can use to create an array of column headers (i.e. the dataset's 'keys').
This is useful because (a) it's simpler code and (b) the headers in the array are in the same order that they appear in the dataset.
So, for the above dataset:
headers = data.columns
... creates the same array as:
headers = Object.keys(data[0])
... but the array of column names is in a predictable order.
Based on the documentation here:
http://docs.composite.net/Data/AccessingDataWithCSharp/How-to-Query-Data-Using-LINQ#_How_to_Query
I need to query data in a table using a filter in type string[int1,int2,int3..] and can't work out how to go about it.
The string[] comes from a different table field which stores id values of a multiselect element on a form:
Table 'Profile' (AGlobal.profile) contains columns:
Id Types(profile_accomtypes)
1 1,2
2 4,7
3 12,4,6
4 3,6,9
Then I have a static table 'TypeDesc' (ALocal.proptype) listing a total of 12 'Type' values:
Id Description(proptype_names)
1 The first description
2 The second description
........
12 The twelfth description
I created a strongly coded class enabling me to easily handle the form content on submit from the client. Within the form was a couple of multiselects (one of them being 'Types" above in the Profile datatype table.) Each of the multiselects are passed to the server in serialized JSON format where I string.Join the 'Types' values with a comma separator to save into the Profile.Types column.
Now I want to serve the selections in a profile page to the client by loading the Types string[] of Profile Id and using the int id values to filter the TypeDesc table to only select the Type values with Description so that I can render the descriptions as a bullet list on the client.
The filter Types in the Profile table are always id integers
My code I'm using is:
var myProftype =
(from d in connection.Get<AGlobal.profile>() // find multiselected type string values
where d.Id == StUserSet.utoken
select d).First();
string sProftype = myProftype.profile_accomtypes;
string[] sTypes = sProftype.Split(',');
// now filter proptypes to sTypes
var myTAccomtypes =
(from d in connection.Get<ALocal.proptype>() // get all the types from the DB
where(r => sTypes.Contains(r.Field<int>("Id"))) //Lambda ?
select d).All;
StringBuilder sb = new StringBuilder(0); //create a bullet list string
// Loop over strings
foreach (string s in myTAccomtypes)
{
sb.append("<dd>"+ s +"</dd>");
}
TuAccomtypes = sb.ToString(); // pass string to JQuery Taconite as part of AJAX response to alter DOM.
I have an error on the Lambda trying to filter my types.
In VS2010:
Error = Cannot convert lambda expression to type bool because its not a delegate type.
I also do not know how to go about parsing the sTypes variables to int (if I need to) so that the filter works :(
Where am I going wrong? Is there a cleaner way to filter a dataset against a comma separated list queried from a column field within a db table?
Thank you for any help/ideas in advance.
Martin.
I'm not entirely sure about your model, but I think this will work for you. I changed your linq, and combined some statements. I'm also casting your Id field to string so that it can be found correctly in the array.Contains() function. You might want to do the reverse of casting your strings to ints and comparing that way, but that's up to you.
var myProftype = profiles.First(p => p.Id == StUserSet.utoken);
string sProftype = myProftype.profile_accomtypes;
string[] sTypes = sProftype.Split(',');
var myTAccomtypes = propTypes.Where(r => sTypes.Contains(r.Field<int>("Id").ToString()));
StringBuilder sb = new StringBuilder(0);
foreach (PropType s in myTAccomtypes)
{
sb.Append("<dd>" + s.Description + "</dd>");
}
Once splitting the string var from the original Linq query (which identified a single field with a joined string of comma separated id numbers.) I wasn't able to use "Contains" properly.
I cast the second Linq query ToList which evaluated the collection.
Then instead of working with a full result I limited the result to just the id and name fields.
Relying on an article posted by Vimal Lakhera:
http://www.c-sharpcorner.com/uploadfile/VIMAL.LAKHERA/convert-a-linq-query-resultset-to-a-datatable/
I converted the result set into a DataTable which allowed easy looping and selection of fields to output as an html string as part of a JQuery Taconite callback.
Here's what works for me...
// now filter proptypes to selected Types|
var myTAccomtypes = from d in connection.Get<ALocal.proptype>().ToList()
// ToList() will evaluate collection, you cannot pass sTypes array of integers to a sql query, at least not in that way
where sTypes.Contains(d.proptype_id.ToString())
select new { d.proptype_id, d.proptype_name };
DataTable AcomType = LINQToDataTable(myTAccomtypes);
StringBuilder sb = new StringBuilder();
// Loop over table rows
foreach (var row in AcomType.Rows.OfType<DataRow>().Take(19)) // will .Take up to a maximum of x rows from above
{
sb.Append("<dd>");
sb.Append(row["proptype_name"].ToString());
sb.Append("</dd>");
}
HldUserSet.TuAccomtypes = sb.ToString();
//HldUserSet.TuAccomtypes = string.Join(",", myTAccomtypes); //Check query content
Using Vimal's 'LINQToDataTable" with the tweak in the LINQ request means that I can use the class in numerous places of the site very quickly.
This works a treat for those with a single string of joined id's in the form of "2,7,14,16" that need to be split and then used to filter against a wider collection matching the id's from the string to record id numbers in a different collection.
I have gridview named myGridView with 800k rows. One of the columns is named NAME and it can have values Alex (1) where one is the number of current reccord for Alex. When I insert new reccord for Alex I want it to be with NAME value "Alex (n)" where n is the smallest number which is not taken. I think I should do some filter like this: var rows = (all objects in gridview).Select(rows where NAME.IndexOf( "Alex (" ) > -1)
And this will return me all the records for Alex ( some number) and now I have to filter by number I suppose... How to do the exact filter which to return me the smallest number which is not taken yet? Can it be faster?
First, I should mention that the code you have pasted won't work. This is because the grid does not provide the rows collection. Also, even if this code works, it will work very slowly because it will result in filtering of 800k rows on the web server. Don't you think that it is better to request the required information from the DB server, which is optimized to work with such queries, and which will be able to process your request faster?
I'm developping a web application using google appengine and django, but I think my problem is more general.
The users have the possibility to create tables, look: tables are not represented as TABLES in the database. I give you an example:
First form:
Name of the the table: __________
First column name: __________
Second column name: _________
...
The number of columns is not fixed, but there is a maximum (100 for example). The type in every columns is the same.
Second form (after choosing a particular table the user can fill the table):
column_name1: _____________
column_name2: _____________
....
I'm using this solution, but it's wrong:
class Table(db.Model):
name = db.StringProperty(required = True)
class Column(db.Model):
name = db.StringProperty(required = True)
number = db.IntegerProperty()
table = db.ReferenceProperty(table, collection_name="columns")
class Value(db.Model):
time = db.TimeProperty()
column = db.ReferenceProperty(Column, collection_name="values")
when I want to list a table I take its columns and from every columns I take their values:
data = []
for column in data.columns:
column_data = []
for value in column.values:
column_data.append(value.time)
data.append(column_data)
data = zip(*data)
I think that the problem is the order of the values, because it is not true that the order for one column is the same for the others. I'm waiting for this bug (but until now I never seen it):
Table as I want: as I will got:
a z c a e c
d e f d h f
g h i g z i
Better solutions? Maybe using ListProperty?
Here's a data model that might do the trick for you:
class Table(db.Model):
name = db.StringProperty(required=True)
owner = db.UserProperty()
column_names = db.StringListProperty()
class Row(db.Model):
values = db.ListProperty(yourtype)
table = db.ReferenceProperty(Table, collection_name='rows')
My reasoning:
You don't really need a separate entity to store column names. Since all columns are of the same data type, you only need to store the name, and the fact that they are stored in a list gives you an implicit order number.
By storing the values in a list in the Row entity, you can use an index into the column_names property to find the matching value in the values property.
By storing all of the values for a row together in a single entity, there is no possibility of values appearing out of their correct order.
Caveat emptor:
This model will not work well if the table can have columns added to it after it has been populated with data. To make that possible, every time that a column is added, every existing row belonging to that table would have to have a value appended to its values list. If it were possible to efficiently store dictionaries in the datastore, this would not be a problem, but list can really only be appended to.
Alternatively, you could use Expando...
Another possibility is that you could define the Row model as an Expando, which allows you to dynamically create properties on an entity. You could set column values only for the columns that have values in them, and that you could also add columns to the table after it has data in it and not break anything:
class Row(db.Expando):
table = db.ReferenceProperty(Table, collection_name='rows')
#staticmethod
def __name_for_column_index(index):
return "column_%d" % index
def __getitem__(self, key):
# Allows one to get at the columns of Row entities with
# subscript syntax:
# first_row = Row.get()
# col1 = first_row[1]
# col12 = first_row[12]
value = None
try:
value = self.__dict__[Row.__name_for_column_index]
catch KeyError:
# The given column is not defined for this Row
pass
return value
def __setitem__(self, key, value):
# Allows one to set the columns of Row entities with
# subscript syntax:
# first_row = Row.get()
# first_row[5] = "New values for column 5"
self.__dict__[Row.__name_for_column_index] = value
# In order to allow efficient multiple column changes,
# the put() can go somewhere else.
self.put()
Why don't you add an IntegerProperty to Value for rowNumber and increment it every time you add a new row of values and then you can reconstruct the table by sorting by rowNumber.
You're going to make life very hard for yourself unless your user's 'tables' are actually stored as real tables in a relational database. Find some way of actually creating tables and use the power of an RDBMS, or you're reinventing a very complex and sophisticated wheel.
This is the conceptual idea I would use:
I would create two classes for the data-store:
table this would serve as a
dictionary, storing the structure of
the pseudo-tables your app would
create. it would have two fields :
table_name, column_name,
column_order . where column_order
would give the position of the
column within the table
data
this would store the actual data in
the pseudo-tables. it would have
four fields : row_id, table_name,
column_name , column_data. row_id
would be the same for data
pertaining to the same row and would
be unique for data across the
various pseudo-tables.
Put the data in a LongBlob.
The power of a database is to be able to search and organise data so that you are able to get only the part you want for performances and simplicity issues : you don't want the whole database, you just want a part of it and want it fast. But from what I understand, when you retrieve a user's data, you retrieve it all and display it. So you don't need to sotre the data in a normal "database" way.
What I would suggest is to simply format and store the whole data from a single user in a single column with a suitable type (LongBlob for example). The format would be an object with a list of columns and rows of type. And you define the object in whatever language you use to communicate with the database.
The columns in your (real) database would be : User int, TableNo int, Table Longblob.
If user8 has 3 tables, you will have the following rows :
8, 1, objectcontaintingtable1;
8, 2, objectcontaintingtable2;
8, 3, objectcontaintingtable3;