Simple.data select top N records - simple.data

I'm using Simple.Data to select data from a table and am wondering if there is a way to select the top 10 records from the table.
Something like:
var result = _database.UserList.All()
.Select(_database.UserList.Name).Take(10) -- or .Top(10)

Something exactly like:
var result = _database.UserList.All()
.Select(_database.UserList.Name).Take(10);
More info on Take and Skip in this blog post: http://blog.markrendle.net/simple-data-0-8-0-and-more/
While we're here, it's worth mentioning that if you just want those names as strings, you can do this:
var result = _database.UserList.All()
.Select(_database.UserList.Name)
.Take(10)
.ToScalarList<string>();

Related

Aggregation Queries

Is it possible to do the following query in SQLite.Swift without resorting to arbitrary SQL (which I do have working but would prefer to avoid)?
select table1.id, sum(table1.col1*table2.col2)
from table1, table2
where table1.id=table2.id
group by table1.id
I've attempted the following: the SQL (through asSQL()) appears to be correct, but I can't find a way to reference the aggregate column from the returned row.
let query = table1.select(id, (table1[column1]*table2[column2]).sum
.join(table2, on: table1[id] == table2[id])
.group(id)
Can you alias columns somehow?
OK, I've found the solution, and it only took me 2 days!
The way to alias a column in SQLite.swift is to use an expression.
The name of the expression becomes the column alias.
So instead of
let query = table1.select(id, (table1[column1]*table2[column2]).sum)
.join(table2, on: table1[id] == table2[id])
.group(id)
Use:
let aggrColumn = (table1[column1]*table2[column2]).sum
let query = table1.select(id, aggrColumn)
.join(table2, on: table1[id] == table2[id])
.group(id)
let results = try db.prepare(query)
for row in results {
myAggrColumn = try row.get(aggrColumn)
}
Using
select id, sum(table1.col1*table2.col2)
from table1, table2
were table1.id=table2.id
group by id
Will result (see below for corrections) in 2 columns, namely id and sum(table1,col*table2.col2)
However both uses of id would be ambiguous as coded as there are two such source columns.
As such the query should be changed (see following code whihc assumes you want the id from table1 (shouldn't matter if table2 were used due to the join))
Additionally were is not a keyword, it should be WHERE
An alias would likely make things easier you make an alias using the AS keyword. The folloiwng also includes AS mysumcolumn thus the resultant columns will be id and mysumcolumn
select table1.id, sum(table1.col1*table2.col2) AS mysumcolumn
from table1, table2
where table1.id=table2.id
group by table1.id
Running this with no data results in :-

nature of SELECT query in MVC and LINQ TO SQL

i am bit confused by the nature and working of query , I tried to access database which contains each name more than once having same EMPid so when i accessed it in my DROP DOWN LIST then same repetition was in there too so i tried to remove repetition by putting DISTINCT in query but that didn't work but later i modified it another way and that worked but WHY THAT WORKED, I DON'T UNDERSTAND ?
QUERY THAT DIDN'T WORK
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
QUERY THAT WORKED of which i don't know how ?
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
why 2nd worked exactly like i wanted (picking each name 1 time)
i'm using mvc 3 and linq to sql and i am newbie.
Both queries are different. I am explaining you both query in SQL that will help you in understanding both queries.
Your first query is:
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName], [t0].[Dept]
FROM [EmployeeAtd] AS [t0]
Your second query is:
(from n in EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct()
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName] FROM [EmployeeAtd] AS
[t0]
Now you can see SQL query for both queries. First query is showing that you are implementing Distinct on all columns of table but in second query you are implementing distinct only on required columns so it is giving you desired result.
As per Scott Allen's Explanation
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
The docs for Distinct are clear – the method uses the default equality comparer to test for equality, and the default comparer sees 4 distinct object references. One way to get around this would be to use the overloaded version of Distinct that accepts a custom IEqualityComparer.
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
Turns out the C# compiler overrides Equals and GetHashCode for anonymous types. The implementation of the two overridden methods uses all the public properties on the type to compute an object's hash code and test for equality. If two objects of the same anonymous type have all the same values for their properties – the objects are equal. This is a safe strategy since anonymously typed objects are essentially immutable (all the properties are read-only).
Try this:
var names = DataContext.EmployeeAtds.Select(x => x.EmplName).Distinct().ToList();
Update:
var names = DataContext.EmployeeAtds
.GroupBy(x => x.EmplID)
.Select(g => new { EmplID = g.Key, EmplName = g.FirstOrDefault().EmplName })
.ToList();

LINQ - listview - 2 levels of data in one table

I have been trying to solve this problem and I can't seem to figure it out. I'm not sure if it's because of my db design and LINQ, but I'm hoping for some direction here.
My db table:
Id         Name         ParentId
1          Data1        null
2          Data2        null
3          Data3        null
4          Data4        1
5          Data5        1
6          Data6        2
7          Data7        2
Basically Data1 and Data2 are the top levels that I want to use for headings and their children will be related based on their ParentID.
I am trying to use a listview to present the data like the following:
Data1
-----
Data4
Data5
Data2
-----
Data6
Data7
I am trying to use a combination of LINQ and listview to accomplish this.
The following is the code for the linq query:
var query = from data in mydb.datatable
where data.ParentId == null
select data;
But this only gives the heading level... and unfortunately listview only takes in 1 datasource.
While it's possible with some databases (like SQL Server post 2005) to write recursive queries, I don't believe those get generated by LINQ. On the other hand, if the number of records is sufficiently small, you could materialize the data (to a list) and write a LINQ query that uses a recursive function to generate your list.
This is from memory, but it would look something like this:
Func<int?,IEnumerable<data>> f = null;
f = parentId => {
IEnumerable<data> result = from data in mydb.datatable
where data.ParentId = parentId
select data;
return result.ToList().SelectMany(d=>f(d.Id));
};
That should get you the hierarchy.
If your hierarchy has only two levels you can use a group join and anonymous objects:
var query = from data in mydb.datatable.Where(x => x.ParentId == null)
join child in mydb.datatable.Where(x => x.ParentId != null)
on data.Id equals child.ParentId into children
select new { data, children };
Edit: You will have to convert the data to a collection that can be bound to a ListView. One hack would be to have a list that is only one level deep with spacing in front of the subitems:
var listViewItems = (from item in query.AsEnumerable()
let dataName = item.data.Name
let childNames = item.children.Select(c => " " + c.Name)
from name in dataName.Concat(childNames)
select new ListViewItem(name)).ToArray();
You could also try to find a control that fits better, like a TreeView. You might want to ask a separate question about this issue.
I just wrote up a blog post describing a solution to build a graph from a self-referencing table with a single LINQ query to the database which might be of use. See http://www.thinqlinq.com/Post.aspx/Title/Hierarchical-Trees-from-Flat-Tables-using-LINQ.

Join two columns from Table A to Table B

I have found the answer to my question, but in the wrong format.
Using SQL Alchemy I want to join columns from Table A to one column on Table B.
Table A contains two columns for Location Code. I can retrieve the Location Name by joining on to Table B, but how to do this?
So far I have this:
locationreq = sa.Table("INMPTL_LOCATION_REQUEST", meta.metadata,
sa.Column("request_id", sa.types.String(), primary_key=True),
sa.Column("status", sa.types.String(100)),
sa.Column("new_loc", sa.types.String(), sa.ForeignKey("INMPTL_LOCATIONS_TBL.inmptl_location_code")),
sa.Column("previous_loc", sa.types.String(), sa.ForeignKey("INMPTL_LOCATIONS_TBL.inmptl_location_code")),
autoload=True,
autoload_with=engine)
locationtable = sa.Table("INMPTL_LOCATIONS_TBL", meta.metadata,
sa.Column("INMPTL_LOCATION_CODE", sa.types.Integer(), primary_key=True),
autoload=True,
autoload_with=engine)
orm.mapper(Location, locationtable )
orm.mapper(LocationRequest, locationreq, extension= wf.WorkflowExtension(), properties = {'location':relation(Location)}
If only one of these columns were mapped to the second table, I could call something such as:
model.LocationRequest.location.location_name
But because I am mapping two columns to the same table, it is getting confused.
Does anyone know the proper way to achieve this?
I was going to delete this question, but this is not a duplicate. The answer is here (setting the primary and secondary joins)
orm.mapper(LocationRequest, locationreq, extension= wf.WorkflowExtension(),
properties={
"new_location":relation(Location,
primaryjoin=locationtable.c.inmptl_location_code==locationreq.c.new_loc, lazy = False),
"previous_location":relation(Location,
primaryjoin=locationtable.c.inmptl_location_code==locationreq.c.previous_loc, lazy = False)
})

How to post picking list for a group of sales orders?

I have a custom table with a list of sales orders I want to post picking lists for.
How can I pass them all at once to the SalesFormLetter object to pick them in a group?
I see SalesFormLetter_PickingList\newJournalList is being called, and I was wondering if there was a way I could just pass a simple RecordSortedList in of the sales orders I wanted to pick. That list is of the wrong table though...so that wouldn't work. It looks like I can somehow pass a query but I'm not exactly sure how to do that. Here is the basic code I'm using to post the picking lists:
salesFormLetter = SalesFormLetter::construct(DocumentStatus::PickingList);
salesFormLetter.update(SalesTable::find(_salesId), today(), SalesUpdate::All, AccountOrder::None, NoYes::No, NoYes::Yes);
This involves setting up a query to select your sales orders then calling the chooseLines to select the orders.
by: Jubal1234Posted on 2010-07-27 at 04:13:28ID: 33296972
Found the solution:
SalesFormLetter salesFormLetter;
QueryRun queryRun;
Query query;
str strSalesTable = "V683904, V683905, V683906";
;
salesFormLetter = SalesFormLetter::construct(DocumentStatus::PackingSlip);
query = new Query(QueryStr(SalesUpdate));
query.dataSourceTable(tablenum(SalesTable)).addRange(fieldnum(SalesTable, SalesId)).value(strSalesTable);
queryRun = new QueryRun(query);
salesFormLetter.chooseLinesQuery(queryRun);
salesFormLetter.transDate(systemdateget());
salesFormLetter.specQty(SalesUpdate::All);
salesFormLetter.printFormLetter(false);
salesFormLetter.createParmUpdate();
salesFormLetter.chooseLines(null,true);
salesFormLetter.reArrangeNow(true);
salesFormLetter.run();
Case closed

Resources