仅在本地开发环境中获取数据的存储库
Repository fetching data only in local development environment
我有一个 ASPNET 样板项目,在一个应用程序服务中使用存储库访问数据库中的一些数据
public class AnAppService : AsyncCrudAppService<MyEntity, MyEntityDto, int, PagedAndSortedResultRequestDto, MyEntityDto, MyEntityDto>, IAnAppService
{
private readonly IRepository<UserTeam> _userTeamsRepository;
public AnAppService(IRepository<MyEntity> repository,
IRepository<UserTeam> userTeamsRepository)
: base(repository)
{
_userTeamsRepository = userTeamsRepository;
}
public override Task<MyEntityDto> Create(MyEntityDto input)
{
[...]
var myDbContext = _myDbContextProvider.GetDbContext();
var uteams = // Here the items have null User objects, though it was included in the query
myDbContext.UserTeams
.Include(ut => ut.User)
.Where(ut => ut.Team.Id == teamId)
.ToList();
[...]
}
}
}
在开发过程中,一切正常,并获取了链接数据。
现在我已经将它部署在 IIS 7 服务器上,但它不再工作了。调试,可以看到defaultUsers
列表不为空(而且项数等于开发机中的项数),但是单项为null。
我在两种环境中使用具有相同数据库的相同用户。
这是 UserTeam
实体的定义。它只是 Boilerplate 的 User
实体和我的 Team
实体之间的多对多映射。
public class UserTeam : Entity<int>
{
public User User { get; set; }
public Team Team { get; set; }
}
你怎么看这个?
更新 1:
我直接执行了 SQL 查询,只是为了检查它是否可能是样板问题或其他问题。这是我的代码运行(方法相同)
string queryString = "SELECT u.name name FROM UserTeams ut join AbpUsers u on ut.UserId = u.Id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
var name = reader["name"]; // The name variable has a value
}
}
好的,数据已获取,我没有用户数据的空值。似乎 ASPNET 样板、Entity Framework 核心和 SQL 引擎之间出现了问题。你有什么线索吗?
更新 2:
我在考虑User
实体的读取操作的权限问题,所以我检查了这个:
public class AnAppService : AsyncCrudAppService<MyEntity, MyEntityDto, int, PagedAndSortedResultRequestDto, MyEntityDto, MyEntityDto>, IAnAppService
{
private readonly IRepository<User, long> _usersRepository;
public AnAppService(IRepository<MyEntity> repository,
IRepository<UserTeam> userTeamRepository)
: base(repository)
{
_userTeamRepository = userTeamRepository;
}
public override Task<MyEntityDto> Create(MyEntityDto input)
{
[...]
var users = _usersRepository.GetAll();
[...]
}
}
}
这里我在 User
实体上使用一个简单的存储库来读取所有用户。好吧,虽然在开发机器上我可以获取所有用户,但在部署机器上只返回 admin
用户。在这两种情况下,我都使用 admin
用户登录。
我认为 UserTeam
存储库没有获取非空用户,因为出于某种原因,登录用户无法访问 User
table (但它是两个环境的同一用户!)
你怎么看?
问题是您试图以错误的方式访问 DbContext。此外,您不应该从 DbContext 中检索用户列表。您必须使用您已经注入的存储库。
public override Task<MyEntityDto> Create(MyEntityDto input)
{
//...
var uteams = _userTeamsRepository.GetAllIncluding(x=>x.User).Where(ut => ut.Team.Id == teamId).ToList();
//and you need to map uteams to your DTO list.
//var uteamsDto = uteams.MapTo<List<MyTeamDto>>();
//...
}
参见mapping and how to use repositories。
我发现了问题。在生产环境中,我使用 admin
用户登录,但没有选择任何租户,所以我登录的是 .
租户,显示为
Current tenant: Not selected
在登录页面上。
使用 Default
租户(或任何工作租户)登录修复了问题
我有一个 ASPNET 样板项目,在一个应用程序服务中使用存储库访问数据库中的一些数据
public class AnAppService : AsyncCrudAppService<MyEntity, MyEntityDto, int, PagedAndSortedResultRequestDto, MyEntityDto, MyEntityDto>, IAnAppService
{
private readonly IRepository<UserTeam> _userTeamsRepository;
public AnAppService(IRepository<MyEntity> repository,
IRepository<UserTeam> userTeamsRepository)
: base(repository)
{
_userTeamsRepository = userTeamsRepository;
}
public override Task<MyEntityDto> Create(MyEntityDto input)
{
[...]
var myDbContext = _myDbContextProvider.GetDbContext();
var uteams = // Here the items have null User objects, though it was included in the query
myDbContext.UserTeams
.Include(ut => ut.User)
.Where(ut => ut.Team.Id == teamId)
.ToList();
[...]
}
}
}
在开发过程中,一切正常,并获取了链接数据。
现在我已经将它部署在 IIS 7 服务器上,但它不再工作了。调试,可以看到defaultUsers
列表不为空(而且项数等于开发机中的项数),但是单项为null。
我在两种环境中使用具有相同数据库的相同用户。
这是 UserTeam
实体的定义。它只是 Boilerplate 的 User
实体和我的 Team
实体之间的多对多映射。
public class UserTeam : Entity<int>
{
public User User { get; set; }
public Team Team { get; set; }
}
你怎么看这个?
更新 1:
我直接执行了 SQL 查询,只是为了检查它是否可能是样板问题或其他问题。这是我的代码运行(方法相同)
string queryString = "SELECT u.name name FROM UserTeams ut join AbpUsers u on ut.UserId = u.Id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
var name = reader["name"]; // The name variable has a value
}
}
好的,数据已获取,我没有用户数据的空值。似乎 ASPNET 样板、Entity Framework 核心和 SQL 引擎之间出现了问题。你有什么线索吗?
更新 2:
我在考虑User
实体的读取操作的权限问题,所以我检查了这个:
public class AnAppService : AsyncCrudAppService<MyEntity, MyEntityDto, int, PagedAndSortedResultRequestDto, MyEntityDto, MyEntityDto>, IAnAppService
{
private readonly IRepository<User, long> _usersRepository;
public AnAppService(IRepository<MyEntity> repository,
IRepository<UserTeam> userTeamRepository)
: base(repository)
{
_userTeamRepository = userTeamRepository;
}
public override Task<MyEntityDto> Create(MyEntityDto input)
{
[...]
var users = _usersRepository.GetAll();
[...]
}
}
}
这里我在 User
实体上使用一个简单的存储库来读取所有用户。好吧,虽然在开发机器上我可以获取所有用户,但在部署机器上只返回 admin
用户。在这两种情况下,我都使用 admin
用户登录。
我认为 UserTeam
存储库没有获取非空用户,因为出于某种原因,登录用户无法访问 User
table (但它是两个环境的同一用户!)
你怎么看?
问题是您试图以错误的方式访问 DbContext。此外,您不应该从 DbContext 中检索用户列表。您必须使用您已经注入的存储库。
public override Task<MyEntityDto> Create(MyEntityDto input)
{
//...
var uteams = _userTeamsRepository.GetAllIncluding(x=>x.User).Where(ut => ut.Team.Id == teamId).ToList();
//and you need to map uteams to your DTO list.
//var uteamsDto = uteams.MapTo<List<MyTeamDto>>();
//...
}
参见mapping and how to use repositories。
我发现了问题。在生产环境中,我使用 admin
用户登录,但没有选择任何租户,所以我登录的是 .
租户,显示为
Current tenant: Not selected
在登录页面上。
使用 Default
租户(或任何工作租户)登录修复了问题