gpt4 book ai didi

c# - ASP.Net Core Web API - ICollection 未显示在 JSON 结果集中

转载 作者:行者123 更新时间:2023-11-30 15:14:21 25 4
gpt4 key购买 nike

我正在尝试执行 3 个过程以构建客户对象并将其返回给客户端。但是,在我的 api(服务器端)中,我可以正确地看到结果。但是,不幸的是,结果集中缺少 ICollection 数据(客户端)

我正在使用 Entity Framework OData

所以,这是我的模型:

  public class Customer
{
[Key]
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string VatCode { get; set; }
public string ChamberOfCommerceCode { get; set; }
public DateTime Modified { get; set; }
public DateTime Created { get; set; }
public string LanguageCode { get; set; }
public decimal Discount { get; set; }
public string CustomerManager { get; set; }
public Guid PriceList { get; set; }
public Guid PaymentCondition { get; set; }
// public bool VatLiable { get; set; }
public bool IsBlocked { get; set; }
public bool IsProspect { get; set; }
public bool IsSuspect { get; set; }
public string Website { get; set; }
public string DashboardUrl { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public ICollection<FreeFields> FreeFields { get; set; }
// [NotMapped]
// public Dictionary<string, string> UknownElements { get; set; }
[ForeignKey(nameof(Contacts.Customer))]
public ICollection<Contacts> Contact { get; set; }
[ForeignKey(nameof(Addresses.Customer))]
public ICollection<Addresses> Address { get; set; }
}

如您所见,我们有 2 个 ICollections:Contacts 和 Addresses。这是这两个的模型:

联系人模型

public class Contacts
{
[Key]
public Guid Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Initials { get; set; }
public string Function { get; set; }
[Column("Customer")]
public Guid Customer { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public string LanguageCode { get; set; }
public bool IsMainContact { get; set; }
public string Gender { get; set; }
public string Username { get; set; }
}

地址

 public class Addresses
{
[Key]
public Guid Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string CountryCode { get; set; }
public string Type { get; set; }
[Column("Customer")]
public Guid Customer { get; set; }// This Property should be GUID instead of String..
public bool IsMainAddress { get; set; }
public string Route { get; set; }
public string State { get; set; }
}

现在,在我的 Controller 中,我从存储过程中获取数据并创建模型:

  public IList<Customer> GetAllCustomers()
{
//Initialize the objects
IList<Customer> customers = null;
ICollection<Contacts> contacts = null;
ICollection<Addresses> addresses = null;
Dictionary<string, string> thisdict = null;
//Fetch the data from stored procedures
customers = db.Customers.FromSql("SIP_API_MONDIA_Customers_sel").ToList();
contacts = db.Contacts.FromSql("SIP_API_MONDIA_Contacts_sel").ToList();
addresses = db.Addresses.FromSql("SIP_API_MONDIA_Address_sel").ToList();

//Loop through customers and add the contact and addresses when required
foreach(var item in customers)
{
item.Contact = contacts.Where(x => x.Customer == item.Id).ToList();
item.Address = addresses.Where(x => x.Customer == item.Id).ToList();
// item.UknownElements = thisdict;

}
return customers;
}

Tihs 工作得很好,我可以看到 Customers 对象已填充的断点。地址和联系方式也正确。但是,一旦我将它返回给客户,结果就缺少两个 ICollections..

enter image description here

我觉得我遗漏了一个小细节,但我找不到它。

最佳答案

所以首先,如果您遵循命名约定,则无需显式使用属性。 Key 属性可以安全删除。如果将属性名称更改为复数名称,则可以删除 ForeignKey 属性:ContactsAddresses。我强烈建议您对类使用单数名称,对集合导航属性使用复数名称(例如在一对多关系中)。

// Contact is name of class, plural name for property: Contacts
public ICollection<Contact> Contacts { get; set; }

如果您正在使用 OData,您应该构建您的 EDM model (你没有给我们看)。如果您有权访问 DbContext,也不要将存储过程用于简单的 SELECT。您的整个 Controller 逻辑是不必要的,可以替换为:

[EnableQuery]
public IQueryable<Customer> GetAllCustomers()
{
return db.Customers;
}

所以在代码中它看起来像:

客户类

public class Customer
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string VatCode { get; set; }
public string ChamberOfCommerceCode { get; set; }
public DateTime Modified { get; set; }
public DateTime Created { get; set; }
public string LanguageCode { get; set; }
public decimal Discount { get; set; }
public string CustomerManager { get; set; }
public Guid PriceList { get; set; }
public Guid PaymentCondition { get; set; }
public bool IsBlocked { get; set; }
public bool IsProspect { get; set; }
public bool IsSuspect { get; set; }
public string Website { get; set; }
public string DashboardUrl { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public ICollection<FreeFields> FreeFields { get; set; }

public ICollection<Contact> Contacts { get; set; }
public ICollection<Address> Addresses { get; set; }
}

联系类

public class Contact
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Initials { get; set; }
public string Function { get; set; }
public Guid Customer { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public string LanguageCode { get; set; }
public bool IsMainContact { get; set; }
public string Gender { get; set; }
public string Username { get; set; }

public Guid CustomerId { get; set; }
// If you want to use class reference navigation property (also called as "hard reference").
// That can be used in "$expand" or "$select" for example.
// Uncomment the following line:
// public Customer Customer { get; set }
}

地址类

public class Address
{
public Guid Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string CountryCode { get; set; }
public string Type { get; set; }
public bool IsMainAddress { get; set; }
public string Route { get; set; }
public string State { get; set; }

public Guid CustomerId { get; set; }
// If you want to use class reference navigation property (also called as "hard reference").
// That can be used in "$expand" or "$select" for example.
// Uncomment the following line:
// public Customer Customer { get; set }
}

构建您的 EDM 模型:

public class MyModelBuilder
{
public IEdmModel GetEdmModel(IServiceProvider serviceProvider)
{
var builder = new ODataConventionModelBuilder(serviceProvider);

builder.EntitySet<Address>("Addresses")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select();// Allow for the $select Command;

builder.EntitySet<Contact>("Contacts")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select() // Allow for the $select Command
.Expand();

builder.EntitySet<Customer>("Customers")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select() // Allow for the $select Command
.Expand();

return builder.GetEdmModel();
}
}

启动中使用它:

public void ConfigureServices(IServiceCollection services)
{
// ... Other Configurations

services.AddOData();
services.AddTransient<MyModelBuilder>();

// ... MVC Service Configurations
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, MyModelBuilder modelBuilder)
{
// ... Other Configurations

app.UseMvc(routeBuilder =>
{
routeBuilder.MapODataServiceRoute("ODataRoutes", "odata", modelBuilder.GetEdmModel(app.ApplicationServices));
});
}

最后创建 Controller :

[Produces("application/json")]
public class CustomersController : ODataController
{
private readonly MyDbContext _context;

public CustomersController (MyDbContext context) => _context = context;

[EnableQuery]
public IQueryable<Customer> GetAllCustomers() => _context.Customers;
}

(在上面的代码中,我假设您已经正确配置了 DbContext)

现在您应该能够使用 $expand$select 来获取例如所有客户的地址。

HTTP GET /odata/Customers?$expand=Addresses

关于c# - ASP.Net Core Web API - ICollection 未显示在 JSON 结果集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54942349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com