I got a complex data structure like this:
leve1Model->1:level2Model->n:level3Model->1:value1
->1:level4Model->1:value2
What I need is to find all level1Model instances which's level2Model instance contains one level3Model instance which has a certain value1 and which's level4Model instance also has a certain value2.
I am relatively new to Extbase and it's Database abstraction, but I figured I could do something like:
$query->contains('level2Model.level3Model.value1', val1),
but this gives me an error about an unsupported property value1. But even if it worked I don't know how I would make sure that the contained instance also meets the required level4Model->1:value2condition.
So is there a way to properly use the abstraction layer for this kind of query (and how would I go about that?) or do I have to resort to plain sql?
The query builder will not help you much here. If the second level model is stored within an object storage you could query against the uids of these objects. But that's as far as the query builder will take you. Your query is too complex. You would have to split the query into multiple parts and re-filter the results but the performance might be bad. I would suggest using the helper functions for sanitation etc. but passing it the finished sql statement parts (fields, from, where etc. ). Alternatively you could rethink the data structure of this is an essential part of your app to make it more extbase compliant.
Related
This is entity framework:
var department = _context.Departments
.Include(dep => dep.Employees.Select(emp => emp.ContactTypes))
.SingleOrDefault(d => d.Id == departmentId);
Here I expect one department to be returned containing all related employees and all contact types for each employee.
This is ormlite servicestack:
I have no idea. When I look at the docu/samples: https://github.com/ServiceStack/ServiceStack.OrmLite
They write:
Right now the Expression support can satisfy most simple queries with a strong-typed API. For anything more complex (e.g. queries with table joins) you can still easily fall back to raw SQL queries as seen below.
I have seen there is a JoinSqlBuilder class but I do not think it can return nested collections.
Maybe what I want is not possible but maybe I can do a compromise like get all employees for the departmentId. Then I inmemory foreach the employees and fetch all contact types for a certain employeeId. Creating the hierarchy and assigning the lists would still be my job.
But I hope there is a shorter solution.
What would also be fine is when the query however it might look like return an object (Dynamic?) with 3 flat properties: Department, Employees, ContactTypes and assign thoese properties to my DTO.
Ok, please don't take this as a definitive answer, but more just my take on the situation (I don't use service stack very much) however...
When I first started to use EF many years ago, I came across a similar situation, where the references just would not load. Like you I was faced with the likely hood of having to enumerate the individual collections myself and write a lot of extra code for an operation the ORM should be able to handle easily.
What I ended up doing, was to use auto-mapper, which basically reduce all the multiline loops I had everywhere to a single line mapping statement.
Granted, I still had to do one mapping statement for each linked property, but it reduced the code I had to write, and more importantly got me up and running until EF improved, or I found a better way of doing things.
Let me stress, I'm not proposing this as an answer, and it's a bit big for a comment, I'm simply suggesting shifting your thought in a different direction, that may help a better solution come to the surface.
I'm using CoreData in my application for DML statements and everything is fine with it.
However I don't want use NSFetchedResultsController for simple queries like getting count of rows, etc.
I've decided to use fmdb, but don't know actual table names to write sql. Entity and table names don't match.
I've even looked inside .sqllite file with TextEdit but no hope :)
FMResultSet *rs = [db getSchema] doesn't return any rows
Maybe there's a better solution to my problem?
Thanks in advance
Core Data prefixes all its SQL names with Z_. Use the SQL command line tools to check out the your persistent store file to see what names it uses.
However, this is a very complicated and fragile solution. The Core Data schema is undocumented and changes without warning because Core Data does not support direct SQL access. You are likely to make error access the store file directly and your solution may break at random when the API is next updated.
The Core Data API provides the functionality you are seeking. IJust use a fetch request that fetches on a specific value using an NSExpressionDescription to perform a function. This allows you to get information like counts, minimums, maximums etc. You can create and use such fetches independent of a NSFetchedResultsController.
The Core Data API is very feature rich. If you find yourself looking outside the API for a data solution, chances are you've missed something in the API.
I am using Entity Framework for my .NET application. I have been able to return objects and their directly-related objects as well (very convenient), but I am having trouble getting the objects of those objects.
IEnumerable<Lot> i = (((ObjectSet<Car>)_carRepository.GetQuery())
.Include(a => a.CarTypes).Take(10).ToList()
This works and I can access carTypes, however I cannot figure out how to access tables associated with CarTypes (e.g. tables which have fields associated with the car types).
I tried to use a Join however I was unable to figure out how to get it to work right.
All help appreciated.
Include can be chained, but you have to keep in mind that it uses strings rather than lambdas. So you do .Include("CarTypes.Company") if you want a two level include. You can also chain Include statements which means including more than one branch from the same top level--eg. .Include("CarTypes").Include("SomeOtherTypeFromTheSameParentAsCar").
You should keep in mind, though, that deep Include statements may not produce the best possible performance because every part of an Include just adds on to the one query that you are building so you will get a larger and more complex query which does a whole bunch of joins under the covers. Sometimes it's more effective to do a few Includes in one query and then issue a second query to get the rest of your data or something like that.
With EF4 you can also setup lazy loading which can sometimes make this kind of thing even easier (but of course it produces multiple roundtrips rather than one or two very large roundtrips).
I believe you can chain Includes... So you could have something like
.Include(a => a.CarTypes.Company)
If you're just using one or two fields from each type, one possibility might be to create a view in the DB. Then you could add this view to your EF model and access those properties directly.
Background: I have a complex search form that stores the query and it's hash in a cache. Once the cache is set, I redirect to something like /searchresults/e6c86fadc7e4b7a2d068932efc9cc358 where that big long string on the end is the md5 hash of my query. I need to make a new argument for views to know what the hash is good for.
The reason for all this hastle is because my original search form is way to complex and has way to many arguments to consider putting them all into the path and expecting to do the filtering with the normal views arguments.
Now for my question. I have been reading views 2 documentation but not figuring out how to accomplish this custom argument. It doesn't seem to me like this should be as hard as it seems to me like it must be. Leaving aside any knowledge of the veiws api, it would seem that all I need is a callback function that will take the argument from the path as it's only argument and return a list of node id's to filter to.
Can anyone point me to a solution or give me some example code?
Thanks for your help! You guys are great.
PS. I am pretty sure that my design is the best I can come up with, lets don't get off my question and into cross checking my design logic if we can help it.
It's not as easy as you would like to make it.
In views, arguments are used to return objects, fx user, node, term, custom object. So you could make some custom code, to get the "query object". That would only be first step. You then need to get the info from the query object. You could either try making a custom relationship bond with the nodes or build your own filter to make the SQL needed. This can quickly become a confusing time sink.
Instead, I would suggest that you use hook_views_query_alter, which will allow you to alter the query. Since you already have the SQL, it's just a matter of checking for the hash, and if it's there, alter the query. Should be a pretty simple thing to do. Only thing that is a bit tricky, is that you have to make the query with the query object that views uses, but it's not that hard to figure out.
I'm a former classic ASP programmer and sometimes PHP programmer writing my first ASP.NET application. I'm loving the much-improved ADO.NET functions, but I'm feeling the need to write a database class. Partly I want to consolidate the code that actually interacts with the database, and partly I want to reduce what feels like repetition.
A simple database class is not hard to do, but I'm using parameterized queries as one of my security measures. I'm struggling with how to incorporate this into a class. I wrote a function to return the datatype of a column in the database by passing in the table and column name, but I can't think of a robust way to obtain the table and column name from the SQL query.
My design for the class was to have a Query() function for selecting, and an Execute() function for insert/update/delete. (Not opposed to having more public functions, but didn't want to get ahead of myself.) Both functions take a SQL string and a SortedList for the parameters. It might be possible to get the column name by finding the parameter name in the SQL string and looking in front of the equal sign. Likewise, it should be fairly simple to get the table name when the query is insert, update, or delete, because you only work with one table at a time. The big concern is selecting, because there could be one or more joins, inner selects, etc.
Am I headed in the wrong direction? Anything I'm not thinking of that could make my life easier or more difficult? Anybody written a class for this in any language that could offer some advice?
Don't reinvent the wheel. Look into nHibernate or LINQToSQL (or LINQToEntities) for your ORM needs.
Would second the call to find a tried and tested wheel that works for you, especially if this is your first foray into aspnet... there will be plenty else to keep you busy.
Would add a suggestion for SubSonic, which is perhaps a little lighter than nHibernate, but it really depends on the nature of your project, they are both great tools, and both have saved me months of work over the last few years.
I think since this is your first experience in ASP.NET you would be well advised to look into Linq to SQL. Do some tutorials so you get a feel for how it works before you try to code any Linq queries.
The only reasons I can think of to NOT use Linq to SQL in your case would be if you are not using SQL Server (or need to support other DBs either now or in future), or you cannot use .NET 3.5 runtime for some reason.
Good luck
It sounds to me like your "simple database class" is hiding too many details from the classes that need to use it.
I've written classes that contain a SqlCeEngine and expose methods like "LookupDescription(String Code)" ... I think that kind of design is something you should be looking into. And, consider looking into LINQ. It has a lot to offer.