Getting Entities whose keys match list(or array) of ids - linq

I am using CodeFirst EntityFramework. I have a IQueryable<User> Entities that are returned using context.Users; where context is DbContext of EntityFramework. From this list I have to choose those whose Id is contained in an array of Ids (long). Id is primary key of User entity. I have tried the following but getting compiler error.
IQueryable<User> users = GetQueryableUsers();
long [] ids = GetSelectedIds(); //array of long representing Ids key of User entities
users.Intersect(ids); // compilation error
users.Where(user => ids.Contains(user.Id)); //compilation error
Compilation error is (no definition found for Intersect/Contains)
Note: System.Linq is already imported.

Make sure you are referencing System.Linq
e.g. using System.Linq
Then user.Id must be of type long. You've stated in comments that it is long? because you believed that is how you needed to use the primary key. The solution is to use long and make use of the autogenerate id options of the entity framework.
Alternatively a more general case for non primary keys that could be null would be to use the contains option with the value or default operator.
users.Where(user=>ids.Contains(user.id??0));

Your problem is you can't intersect users on long ids. Intersect can only be used on IEnumerables of the same type.
You should use user.Id.GetValueOrDefault() because your ID is long? instead of long.

Related

Passing an element of a collection in the query builder

I would like to make a second request with the id obtained in the previous request.
I have 3 tables:
organization
users
follow_organization (relationship table)
I would like to obtain the number of occurrences in the follow_organization table by passing the id of the organization previously obtained.
$organization = DB::table('organizations')->where('name', $name)->first();
$followers = DB::table('follow_organizations')->where('organization_id', $organization)->count();
Unfortunately, I get the following error message:
Object of class stdClass could not be converted to string.
I understood the problem, I pass a table while the query builder waits for a string.
But I can't find the solution to this problem despite the tons of answers I've read on the internet.
Currently you are passing the whole organization object into the where clause, but you only need the id.
To access the id property you can use $organization->id
DB::table('follow_organizations')->where('organization_id', $organization->id)->count();
Setting and Getting Property Values

Hibernate shows different ID than DB

I have three database views that are mapped in Hibernate as entities.
The entities are in a parent-child relationship (1 parent (A), 2 children(B & C)).
One of the children views (B) uses Oracle's dbms_utility.get_hash_value() to calculate its ID.
This is because it does a UNION over several tables that use different ID sequences and thus the IDs from there may not be unique.
I now have the very puzzling effect that a simple entityManager.find(B.class, id) cannot find the appropriate row.
When I look at the children through a loaded parent (A) entity, I can see that the ID shown in B is completely different from the one in the database. If I use this ID with entityManager.find(B.class, hibernateId), Hibernate finds the appropriate entity.
The database, on the other hand, only returns a value when using the ID shown in the ID column there (and not with the ID Hibernate shows).
Child entity C does not use the hash function and does not show this peculiar behaviour - which means the hash must be responsible.
Does anyone have an idea why?
We found the reason:
Child view B used all of its (content containing) columns as a string concatenation for the hash function.
This included date fields, which were not explicitly formatted when creating the string.
So, when Hibernate selected from the view, it obviously used another format than SQL Developer and thus produced completely different (but consistent) IDs.
Explicitly formatting the used date fields removed the problem.

Are there any possible ways to ignore all paths of JPA Example Matcher

I'm new to Spring JPA.
I has two questions about Example and ExampleMatcher API.
Are there any ways to ignore all paths except some paths which I set matchers. Or are there any ways to ignore all paths if Example object's path has null value. It is quite annoying to set all path names like below:
ExampleMatcher<Product> matcher =ExampleMatcher.matching().ignorePaths("field_a", "field_b");
How to match joined column using Example. For example. Product entity has User entity field as #ManyToOne relation. User entity has several fields but my Example object has User field only filled with userId field. In this case I want to find product data which has user_id foreign key column matching userId field value included in user object included in product Example object.
Sorry for poor English... Actually this is my first question at Stack Overflow.
Thanks for attention.
I'm looking forward for great answers.
Spring Data by default will ignore null values in properties. So you need not ignore paths for null values. We could also use the withIgnoreNullValues() (docs) method call on the matcher to explicitly tell it to ignore null values.
Note primitive values(int,double,etc) if not set will still be used since primitives can't have nulls and use default values instead so you should ignore the primitive properties if not used for matching.
For your second question, you could do something like the below
Product product = new Product();
User user = new User();
user.setId(5); // Id to be matched
product.setUser(user); // Associate User object with Product
Example<Product> example = Example.of(product,matcher);

Different results with selector LINQ on a database view

When I use against a dbase(oracle) View
from f in MYVIEW
where f.Order=="HERE"
select f
I get identical results(rows).
With...
from f in MYVIEW
where f.Order=="HERE"
select f.ColA
I get the correct results returned for the ColA
I know this must be a newbie question. Still learning...thanks in advance
The reason is that EF by default needs to identify uniquely every record. Because of that every entity must have unique key. Views don't have a key so EF infers the key by using all non-nullable columns which don't contain binary data. Now EF expects that these columns will make the entity uniquely identifiable. If they don't you will end with the problem you see in your first example. When EF reads entities from result set it check the key and if the entity with the same key was already created it uses that instance instead of creating a new one -> all records from the result set with the same values in key columns will be represented by the same entity instance. I described today how to avoid this problem with views.
Your second example uses projection. In such case no entity instances are constructed and EF simply returns values.

entity framework returning only one value but the list size is correct

Entity framework returning only one value but the list size is correct
I have a table that does not have primary id and I need to get or select all the values in it.
What I see is when I do the selection with linq the number of objects is correct but it is the first row over and over.
I am simply doing something like this
List<MyValueType> valuesInDB = myDb.MyValueTypes.ToList();
Problem is I may get thousands of rows (which is correct) but the rows all have the same exact data.
I am using VS 2010 and used the wizard to create my EF object.
The problem is that entity framework is not able to work with entity without a key. So if your table doesn't specify a key, entity framework will infer its own. The key created by EF is composed of all non-nullable non-binary columns.
So if you for example have single non-nullable column in your entity which have only very small set of values (like enum) you will be able to load only single entity "per value". The reason is an inner implementation of the context and the state manager which uses Identity map pattern. When data record is retrieved from database, EF will first check an entity key and tries to find an object with the same key in its internal storage. If an object is found it will use that object instead of data record retrieved (despite of different data). If an object with the key is not found a new object is materialized and added to internal storage.
That is the purpose of Identity map - object with given key should be created only once by each context. Identity map is core pattern in ORM.
I wrote about Identity map also in this question.
I would suggest searching for the word "Warning" in your EDM's designer.cs file. It might tell you if Entity Framework is having any issues with your table.
I really can't comment much in the absence of the table design. I tried replicating your problem but wasn't able to do so. Here is what I did:
Created a table with no primary key but it had a unique key on an ID column. Entity Framework was able to infer a primary key and when I fetched the data, I not only got the correct number of rows but also the corrects data in those rows.
Created a table with no primary key and no unique key. Also there was no column called ID. Entity Framework excluded this table in the EDM that was generated. Consequently I wasn't able to query this table at all.This was displayed as a warning in the EDM designer file.
It would be better if you can share the create script for your table.

Resources