实体框架LINQ to SQL翻译:它是如何工作的?

Err*_*ale 5 c# entity-framework

在我的应用程序中,绝不能删除数据库中的数据.

实体有一个属性Deleted,可以设置为true或false.

虚拟删除的实体不能从数据库中出去,从应用程序的角度看它们不能存在.

我通过在我的数据访问层中创建GetAll-方法(例如GetAllUsers)来管理它.这些方法只返回flaged为NOT删除的实体(!Deleted),所有其他方法(例如GetUserById)都使用这些方法检索数据.

见下面的例子......

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

public User GetUserById(string userName)
{
    return GetAllUsers().FirstOrDefault(elt => elt.UserName.Equals(userName));
}
Run Code Online (Sandbox Code Playgroud)

从可靠性的角度来看,这种架构非常好,因为我确信我总是提取未删除的实体,但我担心这样做效率不高.

我的问题非常简单:我的应用程序是select * from User每次请求特定用户时从User表()中提取所有数据,还是实体框架足够智能以理解我想要的内容并转换为类似以下内容的SQL查询:select * from User where userName = @userName

如果我每次需要单个用户时从数据库中提取所有数据,那么如何更改我的代码以便创建正确的查询?我想保留集中化,这样我就不必指定了!在每个LINQ查询中都删除了.

D S*_*ley 6

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.

消息是,你可以很容易地重构这个不改变返回类型IQueryable,并可能破坏现有的代码:

// 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));
}
Run Code Online (Sandbox Code Playgroud)

现在GetUserByID只需在原始查询中附加一个条件,然后将操作推送到数据库而不是在内存中过滤.

  • 在这种情况下,破坏现有代码是一件好事.我怀疑OP想要加载内存中的所有条目.鉴于IQueryable很容易转换为IEnumerable,但突破性的变化将非常少 (2认同)