Я пытаюсь получить список пользователей и связанных с ними компаний и теги, используя Entity Framework Core 2.1.
Когда я использую Включить в запрос, я ожидаю получить все объекты без отложенной загрузки, но когда я открываю объект, я вижу список компаний и тегов, возвращаемых с использованием прокси-сервера и итерации над объектами уходит навсегда.
Вот мой код:
IQueryable<User> usersQuery = _context.Users
.Include(u => u.UserTags).ThenInclude(t => t.Tag)
.Include(u => u.UserCompanies).ThenInclude(c => c.Company);
return usersQuery.ToList();
Мой метод ConfigureServices:
services.AddRouting(options => options.LowercaseUrls = true);
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = StaticConfiguration.DefaultContractResolver;
});
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ContractResolver = StaticConfiguration.DefaultContractResolver
};
services.AddCors();
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseMySql(Configuration.GetConnectionString("DefaultConnection"));
options.UseLazyLoadingProxies();
options.UseOpenIddict();
});
services.AddIdentity<User, UserRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Configure Identity options and password complexity here
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
options.User.RequireUniqueEmail = true;
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore().UseDbContext<ApplicationDbContext>();
})
.AddServer(options =>
{
options.UseMvc();
options.EnableTokenEndpoint("/api/authorazation/token");
options.AllowPasswordFlow();
options.AllowRefreshTokenFlow();
options.AcceptAnonymousClients();
options.SetAccessTokenLifetime(TimeSpan.FromDays(30));
options.SetRefreshTokenLifetime(TimeSpan.FromDays(365));
options.DisableHttpsRequirement(); // Note: Comment this out in production
options.RegisterScopes(
OpenIdConnectConstants.Scopes.OpenId,
OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Phone,
OpenIdConnectConstants.Scopes.Profile,
OpenIdConnectConstants.Scopes.OfflineAccess,
OpenIddictConstants.Scopes.Roles);
})
.AddValidation();
services.AddAuthorization(options =>
{
options.AddPolicy(Policies.Consumer, policy => policy.RequireRole(Roles.Consumer));
options.AddPolicy(Policies.Publisher, policy => policy.RequireRole(Roles.Publisher));
options.AddPolicy(Policies.ConsumerOrPublisher, policy => policy.RequireRole(Roles.Consumer, Roles.Publisher));
options.AddPolicy(Policies.AdministratorOrPublisher, policy => policy.RequireRole(Roles.Administrator, Roles.Publisher));
options.AddPolicy(Policies.Administrator, policy => policy.RequireRole(Roles.Administrator));
});
LoadAllBySuffix(services, "Service", DependencyInjectionType.Singelton);
LoadAllBySuffix(services, "Manager", DependencyInjectionType.Scoped);
LoadAllBySuffix(services, "Repository", DependencyInjectionType.Scoped);
Mapper.Initialize(cfg =>
{
cfg.AddProfile<AutoMapperProfile>();
});
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "PPR API", Version = "v1" });
c.OperationFilter<AuthorizationFilter>();
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "password",
TokenUrl = "/api/authorazation/token",
Description = "Note: Leave client_id and client_secret blank"
});
});
Что мне здесь не хватает?