LINQ Select Many question - linq-to-sql

Can you use SelectMany in a query against your DB and if you can, what type does the column need to be in order to do this? I am messing around with LINQPad and anytime I try to use SelectMany I get an error, and from what I am reading it sounds like the type in your lambda expression has to be a collection.

Houses.SelectMany(h => h.HousesPersons.Select(hp => hp.Person.Name))
If you have 3 Tables. Houses, HousesPersons and Persons.
Houses has a One->Many relationship with Persons using HousesPersons to store HouseId and PersonId.
This query will get you a list of all persons in all houses in a flat list, rather than grouped by House.
EDIT: Sorry I can't get AdventureWorks to work on my machine to use a text book example.

SelectMany projects each element of a sequence (i.e. a property of an object that is an enumeration or list) into an IEnumerable<T> and flattens the resulting sequence of sequences into a single sequence / IEnumerable<T>.
Having said that it could be applicable in i.e. a Linq to Entities environment - you could i.e. select select the navigation properties (related entities) of multiple entities and spit them out in a single list.

Related

Laravel Many to Many Relationship : Pivot VS JSON

i wanted to get your expert opinion about this dilema chosing bewteen JSON or Pivot Table
Let just say we have 2 tables here
people
jobs
A person may have multiple jobs, alas, a jobs might have multiple person subscirbed to it.
What is the best approach to it?
Method 1: JSON
I would have jobs column in people table, that contain json array of that person's jobs id, example : [1,2,4]
Method 2: Pivot
I would create pivot table job_person with job_id and person_id column, well, you know Laravel Eloquent style many to many pivot table
I have done some searching, and i found articels favouring each method, some say JSON better because it musch simpler, others would say Pivot is better due to that is how relationship database should work, etc etc.
But i want to know, which one should i use in what scenario? Like if it is just simple case like above scenario, JSON would be better?
What if there are other variables included like additional pivot columns
(Maybe each pivot also contain status column that can be set to active or past_job)
Or what if in the future we want to be able to get all peoples whom have a specific jobs, in which case Pivot would be preferable i think.
What if instead of jobs, the other table would be books and a person can have an extensive of books making we might have tens, or even hundreed pivot records just for one person? And there will be another hundreed persons?
What if instead of books, the other table were stocks in which case, a person might subscribed / unsubscribed multiple stock multiple times?
And maybe to the basic principle, what is each one's advantages/disadvantages?
Thank you very much
I would rather not choose JSON, as there's no benefit from choosing it, you will sacrifice many of the database features and make querying the data difficult and slow.
What if there are other variables included like additional pivot
columns (Maybe each pivot also contain status column that can be set
to active or past_job)
Job and Person are not dependent on each others, so you need to create an associative table between them something like "PersonJob" and add necessary information to it, this is easy to traverse in Laravel.
Or what if in the future we want to be able to get all peoples whom
have a specific jobs, in which case Pivot would be preferable i think.
You could easily query this using the associative table.
And maybe to the basic principle, what is each one's
advantages/disadvantages?
it just that relational databases are made for this kind of stuff and JSON offer no value just hardship.

How to include related entities in an Entity Framework Core 1.0.1 raw query?

Setup:
ASP .NET Core 1 Web API
MySQL Server Community Edition 5.7
Entity Framework Core 1.0.1 with Pomelo MySQL driver (3 separate contexts, 3 separate databases).
Contexts: MainContext (maindb), Module1Context (module1db), Module2Context (module2db).
I want to execute a query that returns a list of Posts (from Module1Context), but I need to filter them by author rights (from MainContext, User entity).
So, what I am trying to do is execute a query with a JOIN clause to a different database table:
var results = await module1Ctx.Posts.FromSql("select * from `module1db`.`posts` as `p` inner join `maindb`.`users` as `u` on `p`.`AuthorId`=`u`.`Id` where <conditions here>").ToListAsync();
When this executes, I get a SQL Exception telling me that "Sequence contains more than one element". If I select p.*, it will work, but I also need to pull the user data.
The Post entity contains a reference to the user ID (public long AuthorId {get;set;}), and a fake navigation property, NotMapped, as EF couldn't join 2 databases automatically.
My first question is - would this be possible. I have a strong feeling that this will work, but that I am missing something small.
If this doesn't work, I will resort to manually executing the query, using the DbContext's Connection. If I will do this, how can I map the results into a list of Posts, including the User data?
Sequence contains more than one element
This tells you that a column appears more than once. For example if you have "ModifiedDate" column in both tables, when you do select * it will appear twice in the result set (once p.ModifiedDate and once in u.ModifiedDate.
Also additional to this, the columns returned must exactly match the model. No property which is defined in the model must be missing, that's why p.* will work.
But unless your Post model does define fields which represent values from User table, you can't return them, because it must exactly match Post and it's mapped properties.
Ad-hoc support (mapping result to an arbitrary model, like a view model) is not yet implemented in EntityFramework Core 1.0 and is a feature on the roadmap for future versions.
From the EntityFramework Core Roadmap:
Critical O/RM features
...
Raw SQL queries for non-Model types allows a raw SQL query to be used to populate types that are not part of the model (typically for denormalized view-model data).
Edit
Also from the EFCore documentation
Limitations
There are a couple of limitations to be aware of when using raw SQL queries:
SQL queries can only be used to return entity types that are part of your model. There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.
The SQL query must return data for all properties of the entity type.
The column names in the result set must match the column names that properties are mapped to. Note this is different from EF6.x where property/column mapping was ignored for raw SQL queries and result set column names had to match the property names.
The SQL query cannot contain related data. However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

cons of storing comma separated value of ids for custom sort order

We're working a web application (Ruby/Rails + Backbone,jQuery,Javascript) where a user can manage a booklist and drag and drop books to rearrange their order within the list, which has to be persisted.
We have books and a custom collection of books called booklist, for which we have two tables: book and booklist. Since a book could belong to multiple booklists, and a booklist consists of multiple books, they have an m x n relationship, and we have another additional table to store the mapping. Lets say we use this for all purposes. Now when the user wants to re-order the books in her bookshelf, we'd need to store that order.
I can totally see the sense about why storing ids in a column is evil , no doubts about it. What if we have the tables normalized, and for all other cases we'd go through the standard operations.
There are quite a few approaches on storing an additional order column. But still it seems like bad design to store the ids of the books in a booklist in a comma separated list in the booklist table, even assuming that integrity is maintained.
We'd never run into this...
SELECT * FROM users WHERE... OH F#$%CK -
Yes it's bad, you can't order, count, sum (etc) or even do a simple report without depending
on a top level language.
because we'd simply be selecting books based on the booklist id using the join table like the standard approach. (In any case, we're only getting the books as an array as part of the backbone booklist model)
So what if we retrieve the booklist and books for the booklist, and do the sorting programatically on the client side (in this case Javascript?) based on the CSV column.
It appears to be a simple solution because:
Every time the user reorders a book, we simply store all the ids in this one column freshly again. (A user will have at the most 20 to 30 books in a booklist).
We could of course simply ignore invalid ids, i.e. books that have been deleted after the booklist had been created.
What are the disadvantages of this approach, which seems to be simpler than maintaining the sort order and updating other columns every time an order is changed, or using a float or weightage, etc.
As per my knowldege its really violating the rule of RDBMS.Which causes facing many difficulties when applying JOIN.
Hope it will help you.

How to find a list of rows that contain any of the given INTs in a column that contains INTs as comma separated values

I have a case where we are maintaining a table containing resources. This table has a varchar column that contains role ids as comma separated values (I know normalizing SHOULD have been the way to go, but can't change a long running working system). E.g. role_ids column contains '1,4,6,9,10' and another row contains '5,10,15'.
Then, for a user in system, I have the associated role ids as a list, e.g. 4,15. Now I need to find 'any in many', i.e. any resource that may have any of the role ids present in resource.role_ids column.
This question is something similar to this one, but the solution expected is not expected in Grails.
I'm looking for a MySQL solution - either a query or a stored procedure. Though finding a set of resources could have been achieved using 'FIND_IN_SET()', but don't want to perform multiple calls to DB with each of user's role_id list.
Use a function like this one, to turn your lists into individual records, then join everything up normally.

Linq to SQL and Gridview Datasource

I have a question related to this one. I don't want to do a calculation (aggregation), but I need to get display values from an association. In my C# code, I can directly reference the value, because the foreign key constraint made Linq generate all the necessary wiring.
When I specify the IQueryable as the Gridview datasource property, and reference something that is not a column of the primary entity in the result set, I get an error that the column does not exist.
As a newbie to Linq, I am guessing the assignment implicitely converts the IQueryable to a list, and the associations are lost.
My question is, what is a good way to do this?
I assume that I can work around this by writing a parallel query returning an anonymous type that contains all the columns that I need for the gridview. It seems that by doing that I would hold data in memory redundantly that I already have. Can I query the in-memory data structures on the fly when assigning the data source? Or is there a more direct solution?
The gridview is supposed to display the physician's medical group associations, and the name of the association is in a lookup table.
IQueryable<Physician> ph =
from phys in db.Physicians
//from name in phys.PhysicianNames.DefaultIfEmpty()
//from lic in phys.PhysicianLicenseNums.DefaultIfEmpty()
//from addr in phys.PhysicianAddresses.DefaultIfEmpty()
//from npi in phys.PhysicianNPIs.DefaultIfEmpty()
//from assoc in phys.PhysicianMedGroups.DefaultIfEmpty()
where phys.BQID == bqid
select phys;
(source: heeroz.com)
So, based on Denis' answer, I removed all the unneeded stuff from my query. I figured that I may not be asking the right question to begin with.
Anyways, the page shows a physician's data. I want to display all medical group affiliations in a grid (and let the user insert, edit, and update affiliations). I now realize that I don't need to explicitly join in these other tables - Linq does that for me. I can access the license number, which is in a separate table, by referencing it through the chain of child associations.
I cannot reference the medical group name in the gridview, which brings me back to my question:
AffiliationGrid.DataSource = ph.First().PhysicianMedGroups;
This does not work, because med_group_print_name is not accessible for the GridView:
A field or property with the name 'med_group_print_name' was not found on the
selected data source.
Again, bear with me, if it is all too obvious that I don't understand Linq ... because I don't.
Your query seems strange. You should try to simply display
ph = from phys in db.Physicians
where phys.BQID == bqid
select phys;
in your grid. That should work.
Also, why the calls to Load()? If the DataContext is not disposed when the grid is binding, you should not need it.
If you still have issues, can you please post the error message you get, that would help...
Part 2
The problem is that you have the name is effectively not in the PhysMedGroup. You need to navigate one level down to the MedGroupLookup to access the name, since it is a property of that class.
Depending on the technology you are using (it seems to be either WinForms or Web Forms), you will need to configure your data-binding to access MedGroupLookup.med_group_print_name.