SQL Query instead of #JoinTable, when use this approach? - spring

I have a problem where there are courses that have classes with different days. However, I also have the possible days of having classes. Using Spring Data, I created the Class, DayHour and PossibleDaysClass entities. Using the ORM approach, I would have to create a table to "query" between DayHour and PossibleDaysClass entities. In this case, the question arose of, when to use the entities approach and #JoinTable and when to decide to use an approach as a native query?

Related

Are Doctrine relations affecting application performance?

I am working on a Symfony project with a new team, and they decide to stop using Doctrine relations the most they can because of performances issues.
For instance I have to stock the id of my "relation" instead of using a ManyToOne relation.
But I am wondering if it is a real problem?
The thing is, it changes the way of coding to retrieve information and so on.
The performance issue most likely comes from the fact that queries are not optimised.
If you let Doctrine (Symfony component that handle the queries) do the queries itself (by using findBy(), findAll(), findOneBy(), etc), it will first fetch what you asked, then do more query as it will require data from other tables.
Lets take the most common example, a library.
Entities
Book
Author
Shelf
Relations
One Book have one Author, but one Author can have many Books (Book <= ManyToOne => Author)
One Book is stored in one Shelf (Book <= OneToOne => Sheilf)
Now if you query a Book, Doctrine will also fetch Shelf as it's a OneToOne relation.
But it won't fetch Author. In you object, you will only have access to book.author.id as this information is in the Book itself.
Thus, if in your Twig view, you do something like {{ book.author.name }}, as the information wasn't fetched in the initial query, Doctrine will add an extra query to fetch data about the author of the book.
Thus, to prevent this, you have to customize your query so it get the required data in one go, like this:
public function getBookFullData(Book $book) {
$qb=$this->createQueryBuilder('book');
$qb->addSelect('shelf')
->addSelect('author')
->join('book.shelf', 'shelf')
->join('book.author', 'author');
return $qb->getQuery()->getResult();
}
With this custom query, you can get all the data of one book in one go, thus, Doctrine won't have to do an extra query.
So, while the example is rather simple, I'm sure you can understand that in big projects, letting free rein to Doctrine will just increase the number of extra query.
One of my project, before optimisation, reached 1500 queries per page loading...
On the other hand, it's not good to ignore relations in a database.
In fact, a database is faster with foreign keys and indexes than without.
If you want your app to be as fast as possible, you have to use relations to optimise your database query speed, and optimise Doctrine queries to avoid a foul number of extra queries.
Last, I will say that order matter.
Using ORDER BY to fetch parent before child will also greatly reduce the number of query Doctrine might do on it's own.
[SIDE NOTE]
You can also change the fetch method on your entity annotation to "optimise" Doctrine pre-made queries.
fetch="EXTRA_LAZY
fetch="LAZY
fetch="EAGER
But it's not smart, and often don't really provide what we really need.
Thus, custom queries is the best choice.

Querying multiple tables using jpa repository

Suppose if I have 3 entities - User, Skills, Department
and I have repositories corresponding to all of them - UserRepository, SkillRepository, DepartmentRepository.
I understand that the relation mapping between entities i.e. one-one many-many should be specified in the respective entity classes. The question is I want to use all of the 3 entities in a query. How would I do it? A single repository is associated with only one entity right? So, how/where would I write it?
As there are many different ways to specify queries with Spring Data JPA there are various answers to this.
Maybe you don't have to. If entity A references B and you just want to get the Bs with your A you simply use your ARepository to load As and use object navigation to get your Bs. You might read up on eager and lazy loading for more information about how to control this.
If you want referenced entities in the where condition you can use property paths in your query method names: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions
If you are using #Query annotations you can do (almost) whatever you want with JPQL. Among others, you may as well navigate properties to use them in where clauses.
In general, you'd put that query in the matching repository based on the primary entity returned.

LINQ DataContext Object Model, could it be used to manage a changing data structure

I am currently working on a project where we are rewriting software that was originally written in Visual DataFlex and we are changing it to use SQL and rewriting it into a C# client program and a C#/ASP.Net website. The current database for this is really horrible and has just had columns added to table or pipe(|) characters stuck between the cell values when they needed to add new fields. So we have things like a person table with over 200 columns because stuff like 6 lots of (addressline1, addressline2, town, city, country, postcode) columns for storing different addresses (home/postal/accountPostal/ect...).
What we would like to do is restructure the database, but we also need to keep using the current structure so that the original software can still work as well. What I would like to know is would it be possible using Linq to write a DataContext Object Model Class that could sort of interpret the data base structures so that we could continue to use the current database structure, but to the code it could look like we where using the new structure, and then once different modules of the software are rewritten we could change the object model to use the correct data structure???
First of all, since you mention the DataContext I think you're looking at Linq to SQL? I would advice to use the Entity Framework. The Entity Framework has more advanced modeling capabilities that you can use in a scenario as yours. It has the ability to construct for example a type from multiple tables, use inheritance or complex types.
The Entity Framework creates a model for you that consists of three parts.
SSDL which stores how your database looks.
CSDL which stores your model (your objects and the relationships between them)
MSL which tells the Entity Framework how to map from your objects to the database structure.
Using this you can have a legacy database and map this to a Domain Model that's more suited to your needs.
The Entity Framework has the ability to create a starting model from your database (where all tables, columns and associations are mapped) en then you can begin restructuring this model.
These classes are generated as partial so you could extend them by for exampling splitting the database piped fields into separate properties.
Have you also thought about using Views? If possible you could at views to your database that give you a nicer dataschema to work with and then base your model on the views in combination with stored procedures.
Hope this gives you any ideas.

LINQ to SQL classes to my own classes

I'm looking at using LINQ to SQL for a new project I'm working on, but I do not want to expose the LINQ classes to my applications. For example, do an select in link returns a System.Linq.IQueryable<> collection. As well, all the classes generated to represent the database use Table, Column, EntityRef classes and attributes. It's fine if my data access layer has LINQ dependancies, but I don't want my application to.
So my thoughts are that I will have to use the LINQ to SQL generated classes as intermediate classes that are not exposed outside of my data access layer, and create my own classes which the application can use. What is the easiest/effecient way to get the data from the LINQ to SQL classes into my own classes?
I totally agree with your thinking - I would try to avoid exposing LINQ to SQL entities directly to the world.
I would definitely recommend using a "domain model" of your own, either a 1:1 mirror of the underlying LINQ to SQL entities, or a different one.
As long as you have a domain model that is quite similar to the underlying LINQ to SQL entities, you can use tools like AutoMapper to easily shuffle data between your LINQ to SQL entities and your domain model classes. It should be pretty easy and flexible to do it that way!
Rob Conery published a webcast series entitled the MVC-Storefront where he introduces a variation of the repository pattern that accomplishes what you want.
I've used ideas from the screencast on a reasonably large project and was quite pleased with the results.
There are, however, issues with the pattern, particularly around concurrency and detached scenarios that you will want to think about up front before fully committing to it.
I detailed some of my pain with concurrency in this pattern here.
I'll be interested in the responses you get because I'm considering the exact same thing. I want to use the L2S entities classes on our backend but use much lighter-weight entities for application consumption.
Randy
I would advise against using LINQ to SQL on a new project, since Microsoft will no longer be developing this project, except for maybe fine-tuning some issues. LINQ to SQL is perfectly usable and is acceptable, but I would not advise new projects to use it. If you like LINQ to SQL, you should definately look into using Entity Framework instead of LINQ to SQL.
This is my current incarnation of how I am going about doing this:
I have a DataContext class that I created by adding a LINQ to SQL class, and droping tables onto the designer. I called the class MyDataContext and put it in a namespace called Linq. My database has a table called Tag, which generated a class, also in the Linq namespace. I changed all the accessors to internal, so they would not be visible outside of the data access layer.
namespace Linq
{
[System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDb")]
internal partial class MyDataContext : System.Data.Linq.DataContext
{
...
}
[Table(Name="dbo.vTag")]
internal partial class Tag
{
....
}
}
I then created a class called DataAccess which is what will be exposed to any application that references the assembly. I also created my own Tag class. The DataAccess class and my new Tag class are in a different namespace called Data to avoid collisions with the generated classes which are in the Linq namespace. I use Linq to Sql to query for an IList of Linq.Tag objects, then I use Linq to generate me a list of Data.Tag objects from the Linq.Tag objects.
I'd like to hear comments on this to see if there's a more performant way to do this, or one that requires less code. I also wasn't too happy with my use of duplicate class names (Tag) so I'm interested to hear any ideas on naming suggestions too.
namespace Data
{
public class DataAaccess
{
public IList<Tag> List_Tags()
{
using (Linq.MyDataContext dal = new Linq.MyDataContext ())
{
IList<Linq.Tag> lstTags = (from c in dal.Tags select c).ToList();
return (from tag in lstTags
select new Data.Tag()
{
ID = tag.ID,
Name = tag.Name,
Parent_ID = tag.Parent_ID
}).ToList();
}
}
}
}
What you are proposing is having two separate models. That means boilerplate code, which I've found is not necessary. I have more or less the same idea as you, but realized that this would be useless. I've suggested Entity Framework in another answer in this thread, and I want to make that point again here.
What you end up with is a model-soup, where you have to maintain two models instead of just the one. And that is definitely NOT desirable.
To go from the LINQ to SQL classes to your classes is a matter of some fairly straightfoward LINQ to Objects (or just initialisation for single objects).
More fun is going back from your model to the LINQ to SQL objects but this is fairly standard stuff (although something I'm still working out or I'd find you some specific references).

Linq To SQL : Modeling Associations

I have three tables Projects, Users and ProjectMembers. The ProjectMembers table is a mapping table and has only two columns ProjectId and UserId.
In my object model i have two classes Project and User. The Project class has a property IEnumerable<User> Members
I am using an external xml map file for mapping linq to sql associations. I am able to get the Project and the User data but I dont know how to map the Members association.
This sounds like a Many-to-Many mapping (Projects <-> Users).
In which case you are going to run into problems using Linq To SQL. To cut a long story short it does not really support that mapping. There are several workarounds which you can find on google, one of which is altering the partial class to provide the access to the Members/Projects collection on the Project and User classes respectively.
e.g. http://www.iaingalloway.com/2015/06/many-to-many-relationships-in-linq-to-sql.html

Resources