Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework LINQ to SQL translation: how does it work?

In my application the data in the database must never be deleted.

Entities have a property, Deleted, which can be set to true or false.

Entities which are virtually deleted can not go out from the database, they must not exist from the application perspective.

I am managing this by creating GetAll- methods (for example GetAllUsers) in my data access layer. The methods return only entities which are flaged as NOT deleted (!Deleted), and all other methods (for example GetUserById) retrieved data with these methods.

See the example below...

public IEnumerable<User> GetAllUsers()
{
    return _dataContext.Users.Where(element => !element.Deleted);
}

public User GetUserById(string userName)
{
    return GetAllUsers().FirstOrDefault(elt => elt.UserName.Equals(userName));
}

This architecture is very good from the perpsctive of reliability because I'm sure that I always extract NOT deleted entities, but I'm afraid that this is not efficient.

My question is very simple: is my application extracting all data from the User table (select * from User) each time a specific User is requested, or is Entity Framework smart enough to understand what I want and translates to a SQL query of something like: select * from User where userName = @userName?

If I'm extracting all data from the database each time I need a single user, then how can I change my code so that it creates the correct query? I would like to mantain the centralization, so that I don't have to specify !Deleted in each LINQ query.

like image 519
Errore Fatale Avatar asked Sep 25 '15 12:09

Errore Fatale


People also ask

How does LINQ to SQL work?

In LINQ to SQL, the data model of a relational database is mapped to an object model expressed in the programming language of the developer. When the application runs, LINQ to SQL translates into SQL the language-integrated queries in the object model and sends them to the database for execution.

How does a LINQ query transform to a SQL query?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

Does Entity Framework use LINQ to SQL?

Entity Framework Core uses Language-Integrated Query (LINQ) to query data from the database. LINQ allows you to use C# (or your . NET language of choice) to write strongly typed queries.


2 Answers

is my application extracting all data from the User table (select * from User) each time a specific User is requested, or Entity Framework is smart enough to understand what I want and the built SQL queries is something like: select * from User where userName = @userName ?

You are retrieving all users that are not deleted each time. The reason is because GetAllUsers returns an IEnumerable<User> instead of an IQueryable<user>, so you have left the world of Linq-to-EF and are now working in Linq-to-objects, which does all filtering, sorting, etc. in memory and does not go back to the database.

The good news is you can easily refactor this without changing the return type to IQueryable and possibly breaking existing code:

// make the base query private   
private IQueryable<User> GetAllUsersQuery()
{
    return _dataContext.Users.Where(element => !element.Deleted);
}

public IEnumerable<User> GetAllUsers()
{
    return GetAllUsersQuery().AsEnumerable();
}

public User GetUserById(string userName)
{
    return GetAllUsersQuery().FirstOrDefault(elt => elt.UserName.Equals(userName));
}

Now GetUserByID just appends a condition onto the original query, so the operations will then be pushed to the database rather than filtering in-memory.

like image 154
D Stanley Avatar answered Nov 10 '22 00:11

D Stanley


Yes, Entity Framework creates a SQL statement for your query.

Regarding the deleted rows issue, you could create a SQL view and map your entities to this, rather than the actual table. That way you make it far less likely that you'd select deleted rows.

N.B. You can still insert new rows.

CREATE VIEW UsersActive
AS
SELECT *
FROM Users
WHERE Deleted != 1

And then on your entity:

[Table("UsersActive")]
public class User
{
    ...
}
like image 33
Knelis Avatar answered Nov 10 '22 00:11

Knelis