【发布时间】:2019-02-23 06:04:54
【问题描述】:
我正在尝试构建一个 ASP.NET Core API,它返回一个包含一些相关、连接数据的对象。
但是当我使用 Include() 调用 Article 模型时,它会由 EF Core 自动映射。这是有意的,但是.. 发生了意外的映射。
EF Core 为所有对象生成完全映射的对象,从而产生过多的数据。
例如,User 模型具有 Article 属性,当我调用 Article 模型时,User 属性也包含 Article 对象信息。结果,它返回了很多重复的数据。
第一次,我认为它来自
https://docs.microsoft.com/en-us/ef/core/querying/related-data
- 渴望加载
- 显式加载
- 延迟加载
但事实并非如此。
我不知道如何配置 EF Core 不映射里面的所有对象..
*数据库架构和模型
public class Topic
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[HiddenInput(DisplayValue = false)]
public int TopicId { get; set; }
[Required]
[StringLength(20, ErrorMessage = "Title cannot be longer than 20 characters.")]
public string Title { get; set; }
[StringLength(200, ErrorMessage = "Description cannot be longer than 200 characters.")]
public string Description { get; set; }
public byte[] Picture { get; set; }
public string PictureMimeType { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
public DateTime PostDate { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
public DateTime ModifyDate { get; set; }
[Display(Name = "Show")]
public bool ShowFlag { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
public class Article
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[HiddenInput(DisplayValue = false)]
public int ArticleId { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Title cannot be longer than 100 characters.")]
public string Title { get; set; }
public string Content { get; set; }
[StringLength(10, ErrorMessage = "Category cannot be longer than 10 characters.")]
public string Category { get; set; } = "Free";
public byte[] Picture { get; set; }
public string PictureMimeType { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
public DateTime PostDate { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
public DateTime ModifyDate { get; set; }
public int ReadCount { get; set; }
[Required]
[Display(Name = "Show")]
public bool ShowFlag { get; set; }
public int TopicId { get; set; }
public virtual Topic Topic { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
}
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[HiddenInput(DisplayValue = false)]
public int UserId { get; set; }
[StringLength(20, ErrorMessage = "Name cannot be longer than 20 characters.")]
public string Name { get; set; }
[StringLength(255, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
[StringLength(20, ErrorMessage = "Title cannot be longer than 20 characters.")]
public string Title { get; set; }
[StringLength(20, ErrorMessage = "Phone number cannot be longer than 20 characters.")]
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[StringLength(100, ErrorMessage = "Address cannot be longer than 100 characters.")]
public string Address { get; set; }
[StringLength(100, ErrorMessage = "Introduction cannot be longer than 100 characters.")]
public string Introduction { get; set; }
[DataType(DataType.Date)]
public DateTime? Birthdate { get; set; }
public byte[] Picture { get; set; }
public string PictureMimeType { get; set; }
public virtual ICollection<Topic> Topics { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
*控制器代码
var article = await this._context.Articles
.Include(a => a.User)
.Include(a => a.Topic)
.SingleOrDefaultAsync(a => a.ArticleId == id);
*重复数据
{
"articleId": 5,
"title": "Does TaskAll() really wait for all in any case?",
"content": null,
"category": "Threading",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-06-18T07:00:00",
"modifyDate": "2018-06-20T07:47:42.1854485",
"readCount": 101,
"showFlag": true,
"topicId": 1,
"topic": {
"topicId": 1,
"title": "C#",
"description": "About C#",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-05-28T07:00:00",
"modifyDate": "2018-05-28T23:36:04.701311",
"showFlag": true,
"userId": 1,
"user": {
"userId": 1,
"name": "",
"password": null,
"email": "",
"title": "Junior Programmer!!",
"phone": "",
"address": "",
"introduction": "Hey, I'm Jason, most motivated person to be a fullstack programmer! ",
"birthdate": null,
"picture": null,
"pictureMimeType": null,
"permissionId": 0,
"permission": null,
"topics": [],
"articles": [
{
"articleId": 5,
"title": "Does TaskAll() really wait for all in any case?",
"content": null,
"category": "Threading",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-06-18T07:00:00",
"modifyDate": "2018-06-20T07:47:42.1854485",
"readCount": 101,
"showFlag": true,
"topicId": 1,
"userId": 1
}
]
},
"articles": [
{
"articleId": 5,
"title": "Does TaskAll() really wait for all in any case?",
"content": null,
"category": "Threading",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-06-18T07:00:00",
"modifyDate": "2018-06-20T07:47:42.1854485",
"readCount": 101,
"showFlag": true,
"topicId": 1,
"userId": 1,
"user": {
"userId": 1,
"name": "",
"password": null,
"email": "",
"title": "Junior Programmer!!",
"phone": "",
"address": "",
"introduction": "Hey, I'm Jason, most motivated person to be a fullstack programmer! ",
"birthdate": null,
"picture": null,
"pictureMimeType": null,
"topics": [],
"articles": []
}
}
]
},
"userId": 1,
"user": {
"userId": 1,
"name": "",
"password": null,
"email": "",
"title": "Junior Programmer!!",
"phone": "",
"address": "",
"introduction": "Hey, I'm Jason, most motivated person to be a fullstack programmer! ",
"birthdate": null,
"picture": null,
"pictureMimeType": null,
"topics": [
{
"topicId": 1,
"title": "C#",
"description": "About C#",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-05-28T07:00:00",
"modifyDate": "2018-05-28T23:36:04.701311",
"showFlag": true,
"userId": 1,
"articles": [
{
"articleId": 5,
"title": "Does TaskAll() really wait for all in any case?",
"content": null,
"category": "Threading",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-06-18T07:00:00",
"modifyDate": "2018-06-20T07:47:42.1854485",
"readCount": 101,
"showFlag": true,
"topicId": 1,
"userId": 1
}
]
}
],
"articles": [
{
"articleId": 5,
"title": "Does TaskAll() really wait for all in any case?",
"content": null,
"category": "Threading",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-06-18T07:00:00",
"modifyDate": "2018-06-20T07:47:42.1854485",
"readCount": 101,
"showFlag": true,
"topicId": 1,
"topic": {
"topicId": 1,
"title": "C#",
"description": "About C#",
"picture": null,
"pictureMimeType": null,
"postDate": "2018-05-28T07:00:00",
"modifyDate": "2018-05-28T23:36:04.701311",
"showFlag": true,
"userId": 1,
"articles": []
},
"userId": 1
}
]
}
}
【问题讨论】:
-
使用数据传输对象
标签: entity-framework-core asp.net-core-2.0 asp.net-core-webapi asp.net-core-2.1