this has the advanteages of the IQueryable? - c#-4.0

If I dont' wrong, I can get the data from a database in to ways:
First with an IEnumerable:
myContext.MyTable.ToList();
With an IQeryable:
IQueryable<MyTable> query = myContext.Mytable;
I know that one of the advantages is that IQueryable execute the conditions in the server, so is more efficient and faster that IEnumerable.
But In my repository, as I return a List, I would like to know if this:
return query.ToList();
has the advantages of the IQueryable.

query.ToList() is the same like myContext.MyTable.ToList(). It returns a collection in memory (the whole database table) and is just an IEnumerable<T>, not an IQueryable<T>. Every further LINQ operator - for example a Where clause - you append, will be performed in memory and not in the database.
If you choose to return IEnumerable<T> or List<T> from your repository you have to design the repository methods so that you can apply filters, sorting, etc. inside of those methods - for example by passing in filter and sort expressions as parameters into the methods or by creating lots of specialized methods for different use cases - like GetOrdersByCustomerId, GetOrdersByShippingDate, etc., etc. If you do it outside of and after calling repository methods you will suffer from poor performance.

Related

Jooq - converting nested objects

the problem which I have is how to convert jooq select query to some object. If I use default jooq mapper, it works but all fields must be mentioned, and in exact order. If I use simple flat mapper, I have problems with multiset.
The problem with simple flat mapper:
class Student {
private final id;
Set<String> bookIds;
}
private static final SelectQueryMapper<Student> studentMapper = SelectQueryMapperFactory.newInstance().newMapper(Studen.class);
var students = studentMapper.asList(
context.select(
STUDENT.ID.as("id),
multiset(
select(BOOK.ID).from(BOOK).where(BOOK.STUDENT_ID.eq(STUDENT.ID)),
).convertFrom(r -> r.intoSet(BOOK.ID)).as("bookIds"))
.from(STUDENT).where(STUDENT.ID.eq("<id>"))
)
Simple flat mapper for attribute bookIds returns:
Set of exact one String ["[[book_id_1], [book_id_2]]"], instead of ["book_id_1", "book_id_2"]
As I already mention, this is working with default jooq mapper, but in my case all attributes are not mention in columns, and there is possibility that some attributes will be added which are not present in table.
The question is, is there any possibility to tell simple flat mapper that mapping is one on one (Set to set), or to have default jooq mapper which will ignore non-matching and disorder fields.
Also what is the best approach in this situations
Once you start using jOOQ's MULTISET and ad-hoc conversion capabilities, then I doubt you still need third parties like SimpleFlatMapper, which I don't think can deserialise jOOQ's internally generated JSON serialisation format (which is currently an array of arrays, not array of objects, but there's no specification for this format, and it might change in any version).
Just use ad-hoc converters.
If I use default jooq mapper, it works but all fields must be mentioned, and in exact order
You should see that as a feature, not a bug. It increases type safety and forces you to think about your exact projection, helping you avoid to project too much data (which will heavily slow down your queries!)
But you don't have to use the programmatic RecordMapper approach that is currently being advocated in the jOOQ manual and blog posts. The "old" reflective DefaultRecordMapper will continue to work, where you simply have to have matching column aliases / target type getters/setters/member names.

AQL: collection not found. non-blocking query

If I run this query:
FOR i IN [
my_collection[*].my_prop,
my_other_collection[*].my_prop,
]
RETURN i
I get this error:
Query: AQL: collection not found: my_other_collection (while parsing)
It's true that 'my_other_collection' may not exist, but I still want the result from 'my_collection'.
How can I make this error non-blocking ?
A missing collection will cause an error and this can not be ignored or suppressed. There is also no concept of late-bound collections which would allow you to evaluate a string as collection reference at runtime. In short: this is not supported.
The question is why you would want to use such a pattern in the first place. I assume that both collections exists, then it will materialize the full array before returning anything, which is presumably memory intensive.
It would be much better to either keep the documents of both collections in a single collection (you may add an extra attribute type to distinguish between them) or to use an ArangoSearch view, so that you can search indexes attributes across collections.
Beyond the two methods already mentioned in the previous answer (Arango search and single collection), you could do this in JavaScript , probably inside Foxx:
Check if collections exist with db_collection(collection-name)
Then build the query string using aql fragments and use union to merge the fragments to pull results from the different collections.
Note that ,if the collections are large, you probably will want to filter that results instead of just pulling all the documents.

Fetching NSManagedObjects based on attributes in related objects with inheritance?

I have a fairly complex CoreData data model with entities inheriting from others and I'm getting an exception when executing a predicate. For example:
#"player.score > 1000";
Where:
Player (abstract)
- name
- tags -> Tag
LocalPlayer : Player
- score
- lives
VirtualPlayer : Player
- difficultyLevel
Tag : NSManagedObject
- name
- color
- player -> Player
I understand why, Tag has a relationship to Player, and score is an attribute on LocalPlayer, so it isn't valid since it isn't on other Player subclasses. But I really don't want lose the hierarchy of my data model.
Is there a way (subqueries, maybe?) to limit my predicate to only run against LocalPlayer objects in the Tag:player->Player releationship? Any suggestions?
Thanks.
If you are attempting to perform a fetch request using this predicate, it is not possible. The predicate is compiled to an SQL statement, and it is validated before sending to the backing database for execution. Interestingly, Core Data implements inheritance in a single, large table. So the SQL statement would actually not fail and return a correct result. But it is failed before execution by the Core Data predicate parser, which validates it against its model. To overcome this, consider promoting the score property to the abstract class Player. Perhaps, store it as an NSNumber, which would allow having a nil value to indicate irrelevance (in cases of VirtualPlayer objects).
You could also reverse your fetch request, fetching all local players with score of 1000, and then taking a list of all the tags:
NSSet* tags = [[moc executeFetchRequest:localPlayersRequest error:NULL] valueForKey:#"#distinctUnionOfSets.tags"];
Note however, that this is less optimal, and you may consider prefetching the tags relationship for quicker union of sets.
You should not have a predicate like this. From a conceptional standpoint, a Player is not guaranteed to have a score. Instead, you should set the entity of your request to LocalPlayer.
Even better, in my opinion, would be to avoid the inheritance complexity altogether. If the attributes list in your question is exhaustive, I would think that you had better simplify the model to just a Player entity to include all the attributes. You could even add a boolean isVirtual to make query filters easier.
Keep it simple and readable. You may "lose the hierarchy" but you will "gain simplicity".

Core Data predicate with multiple to-many operations

Apple's Predicate Programming Guide describes a limitation on Core Data predicates:
The Core Data SQL store supports only one to-many operation per query;
therefore in any predicate sent to the SQL store, there may be only
one operator (and one instance of that operator) from ALL, ANY, and
IN.
I just tested this by creating a fetch request with a compound predicate with two ANY operators in it (wanting to return any objects matching two separate to-many relationships. The request appears to have worked, returning the object I was expecting.
So, is the statement in the guide:
incorrect (or out-of-date)
correct (appears to work, but won't be deterministic, so can't be trusted)
correct (appears to work, but my test is shoddy)
correct (for some other reason)
Thanks

Usage of a correct collection Type

I am looking for a native, or a custom-type that covers the following requirements:
A Generic collection that contains only unique objects like a HashSet<T>
It implements INotifyCollectionChanged
It implements IENumerable<T> (duh) and must be wrappable by a ReadOnlyCollection<T> (duh, duh)
It should work with both small and large numbers of items (perhaps changing inner behaviour?)
the signature of the type must be like UniqueList<T> (like a list, not a key/valuepair)
It does not have to be sortable.
Searchability is not a "must-have".
The main purpose of this is to set up a small mesh/network between related objects.
So this network can only unique objects and there has to be a mechanism that notifies the application when changes in the collection happen.Since it is for a proof-of-concept the scope is purely within the assembly (no db's or fs are of any importance).
What is a proper native type for this or what are the best ingredients to create a composite?
Sounds like you could just wrap HashSet<T> in your own type extremely easily, just to implement INotifyCollectionChanged. You can easily proxy everything you need - e.g. GetEnumerator can just call set.GetEnumerator() etc. Implementing INotifyCollectionChanged should just be a matter of raising the event when an element is added or removed. You probably want to make sure you don't raise the event if either you add an element which is already present or remove an element which isn't already present. HashSet<T>.Add/Remove both return bool to help you with this though.
I wouldn't call it UniqueList<T> though, as that suggests list-like behaviour such as maintaining ordering. I'd call it ObservableSet<T> or something like that.

Resources