不确定我是否使用了正确的术语,但它不是子/父,因为它们不是嵌套对象。在我的应用程序中,我有一个非常标准的User,UserUserGroup和UserGroup对象,UserUserGroup是一个具有相应ID的链接对象。我正在使用Linq-to-SQL,所以不幸的是它没有使用嵌套对象,但它仍然知道这种关系。
考虑以下类和查询我试图返回与特定UserGroup关联的用户列表:
Public Class UserDao
Inherits EntityDao(Of User)
Public Function getListOfUsersByUserGroupName(ByVal userGroupName As String) As IList(Of User)
Dim userList As New List(Of User)
If Not userGroupName Is Nothing Then
Dim userGroupDao As New UserGroupDao()
Dim userUserGroupDao As New UserUserGroupDao()
Dim userGroup As New UserGroup()
userGroup = userGroupDao.getOneByValueOfProperty("Name", userGroupName)
If Not userGroup Is Nothing Then
Dim userUserGroup As IQueryable(Of UserUserGroup) = userUserGroupDao.getListByValueOfProperty("UserGroupId", userGroup.Id)
If Not userUserGroup Is Nothing Then
Dim userDao As New UserDao()
Dim user As New User()
For Each entry As UserUserGroup In userUserGroup
Dim result As UserUserGroup = entry
user = userDao.getOneByValueOfProperty("Id", result.Id)
userList.Add(user)
Next
End If
End If
End If
Return userList
End Function
End Class
无论如何,用更少的线条和更有效率来改善这一点?对于我来说,首先获取所提供的用户组的ID,然后在UserUserGroup中获取结果,其中UserGroupId等于该值,然后从该查询中获取所有用户ID,然后对于每个这些ID,查询User表以获取与该ID对应的对象。对于一个'结果'来说,这似乎很糟糕我运行至少3个查询,每个查询创建并处理dataContexts。看起来它会很费力,特别是对于每个循环,如果有大量的结果返回。
答案 0 :(得分:1)
我认为您在LINQ to SQL中可以相对轻松地完成所需的工作,但从LINQ的角度来看,数据层的结构是出乎意料的。我希望,如果您使用设计器并在数据库中定义关系,那么您将拥有实体集并可以使用它们。使用数据上下文(比如Repository模式)作为查询基础的更自然的方式可能会更好。从本质上讲,您想要的是任何具有任何关联的用户,在这些关联中,与其关联的组包含具有相关名称的组。
编辑:我认为我实际上说的是让LINQ成为LINQ 。 LINQ是一个以数据上下文为中心的ORM(轻量级),您需要考虑从数据上下文角度使用LINQ,以使其真正适合您。如果你坚持以前的数据对象为中心的观点,我想你会对LINQ感到失望。
示例(在C#中) - 这不是关于如何实现存储库的完整示例 用于说明目的。
public class UserRepository : IDisposable
{
private DataContext Context { get; set; }
private bool DisposeContext { get; set; }
public UserRepository() : this( null ) { }
public UserRepository( DataContext context ) // manual constructor injection
{
this.Context = context ?? new MyDataContext();
this.DisposeContext = context == null;
}
public IQueryable<User> GetListOfUsersByUserGroupName( string userGroupName )
{
return Context.Users
.Where( u => u.UserUserGroups
.Any( uug => uug.Groups
.Any( ug => ug.GroupName == userGroupName ) );
}
...
public void SaveChanges()
{
Context.SubmitChanges();
}
// insert canonical IDisposable pattern here and dispose of
// the data context if needed, don't dispose if injected
}
用作:
using (var repository = new UserRepository())
{
var users = repository.GetListOfUsersByUserGroupName( "admin" );
foreach (var admin in users)
{
SendMessage( admin, notification );
admin.LastNotified = DateTime.Now;
}
repository.SaveChanges();
}