C# 实体框架核心:使用include从相关表获取数据

C# 实体框架核心:使用include从相关表获取数据,c#,entity-framework-core,asp.net-core-webapi,C#,Entity Framework Core,Asp.net Core Webapi,我试图从五个表中获取数据:Category-subCategory-secondSubCategory-type-heating,它们都与主表(属性)相关 表(category-subCategory-secondSubCategory)与层(category=>subCategory=>secondSubCategory)是相关的 我试图通过以下方式获取数据: public IActionResult getAllProperties() { var properties = db

我试图从五个表中获取数据:Category-subCategory-secondSubCategory-type-heating,它们都与主表(属性)相关

表(category-subCategory-secondSubCategory)与层(category=>subCategory=>secondSubCategory)是相关的

我试图通过以下方式获取数据:

public IActionResult getAllProperties()
{
      var properties = db.properties
                         .Include(cat => cat.category)
                         .Include(sub => sub.subCategory)
                         .Include(sec => sec.SecondSubCategory)
                         .Include(e => e.heating)
                         .Include(e => e.type)        
                         .OrderByDescending(x => x.id)
                         .ToList();
      return Ok(properties);
}
但返回的数据包含类型字段和加热字段的值,但包含(categoryId和subCategoryId以及secondSubCategoryId)的空值,因为知道这些字段具有值

Property.cs

public class Property
{
    [Key]
    public int id { get; set; }    

    public int typeId { get; set; }
    public type type { get; set; }

    public int heatingId { get; set; }
    public heating heating { get; set; }

    public int? categoryId { get; set; }
    public category category { get; set; }

    public int? subCategoryId { get; set; }
    public subCategory subCategory { get; set; }

    public int? secondSubCategoryId { get; set; }
    public SecondSubCategory SecondSubCategory { get; set; }
}
不包括类别和子类别以及第二子类别的响应:

 {
        "id": 14,        
        "typeId": 1,
        "type": {
            "id": 1,
            "typeName": "Flat"
        },
        "heatingId": 4,
        "heating": {
            "id": 4,
            "heatingName": "Conditioning"
        },
        "categoryId": 1,
        "category": null,
        "subCategoryId": 2,
        "subCategory": null,
        "secondSubCategoryId": 3,
        "secondSubCategory": null
    }
{
        "id": 14,        
        "typeId": 1,
        "type": {
            "id": 1,
            "typeName": "Flat"
        },
        "heatingId": 4,
        "heating": {
            "id": 4,
            "heatingName": "Conditioning"
        },
        "categoryId": null,
        "category": null,
        "subCategoryId": null,
        "subCategory": null,
        "secondSubCategoryId": null,
        "secondSubCategory": null
}
包含类别和子类别以及第二子类别的响应:

 {
        "id": 14,        
        "typeId": 1,
        "type": {
            "id": 1,
            "typeName": "Flat"
        },
        "heatingId": 4,
        "heating": {
            "id": 4,
            "heatingName": "Conditioning"
        },
        "categoryId": 1,
        "category": null,
        "subCategoryId": 2,
        "subCategory": null,
        "secondSubCategoryId": 3,
        "secondSubCategory": null
    }
{
        "id": 14,        
        "typeId": 1,
        "type": {
            "id": 1,
            "typeName": "Flat"
        },
        "heatingId": 4,
        "heating": {
            "id": 4,
            "heatingName": "Conditioning"
        },
        "categoryId": null,
        "category": null,
        "subCategoryId": null,
        "subCategory": null,
        "secondSubCategoryId": null,
        "secondSubCategory": null
}
C类

public class category
  {
    public int id { get; set; }

    public string category_Name { get; set; }

    public IList<subCategory> subCategories { get; set; }
    public Property Property { get; set; }

  }

不能直接包含到属性类别、子类别和子类别对象,因为其中一些对象仅在彼此内部。所以,试着用一种很好的老方法来做到这一点:

public IActionResult getAllProperties()
{
 var properties = ( from p in  db.properties
 join  c in  db.category on p.categoryId equals c.Id into cj
 from c in cj.DefaultIfEmpty()
 join  sc in  db.subCategory on on p.subCategoryId equals sc.Id into scj
 from sc in scj.DefaultIfEmpty()
 join  ssc in  db.secondSubCategory on on p.secondSubCategoryId equals ssc.Id into sscj
 from ssc in sscj.DefaultIfEmpty()
join  h in  db.heatings on p.heatingId equals h.Id 
join  t in  db.types on p.typeId equals t.Id 
orderby  p.id descending
select new Property {
id= p.id 
 typeId=p.typeId,
 type=t,
 heatingId = p.heatingId,
 heating=h, 
 categoryId = p.categoryId,
category =c,
subCategoryId= p.subCategoryId,
subCategory=sc,
secondSubCategoryId=p.secondSubCategoryId,
SecondSubCategory=ssc 
}).ToList();

 return Ok(properties);
}

或者再短一点:

var properties = ( from p in  db.properties
 join  c in  db.category on p.categoryId equals c.Id into cj
 from c in cj.DefaultIfEmpty()
 join  sc in  db.subCategory on on p.subCategoryId equals sc.Id into scj
 from sc in scj.DefaultIfEmpty()
 join  ssc in  db.secondSubCategory on on p.secondSubCategoryId equals ssc.Id into sscj
 from ssc in sscj.DefaultIfEmpty()
orderby  p.id descending
select new Property {
id= p.id 
 typeId=p.typeId,
 type=p.type,
 heatingId = p.heatingId,
 heating=p.heading, 
 categoryId = p.categoryId,
category =c,
subCategoryId= p.subCategoryId,
subCategory=sc,
secondSubCategoryId=p.secondSubCategoryId,
SecondSubCategory=ssc 
}).ToList();

不能直接包含到属性类别、子类别和子类别对象,因为其中一些对象仅在彼此内部。所以,试着用一种很好的老方法来做到这一点:

public IActionResult getAllProperties()
{
 var properties = ( from p in  db.properties
 join  c in  db.category on p.categoryId equals c.Id into cj
 from c in cj.DefaultIfEmpty()
 join  sc in  db.subCategory on on p.subCategoryId equals sc.Id into scj
 from sc in scj.DefaultIfEmpty()
 join  ssc in  db.secondSubCategory on on p.secondSubCategoryId equals ssc.Id into sscj
 from ssc in sscj.DefaultIfEmpty()
join  h in  db.heatings on p.heatingId equals h.Id 
join  t in  db.types on p.typeId equals t.Id 
orderby  p.id descending
select new Property {
id= p.id 
 typeId=p.typeId,
 type=t,
 heatingId = p.heatingId,
 heating=h, 
 categoryId = p.categoryId,
category =c,
subCategoryId= p.subCategoryId,
subCategory=sc,
secondSubCategoryId=p.secondSubCategoryId,
SecondSubCategory=ssc 
}).ToList();

 return Ok(properties);
}

或者再短一点:

var properties = ( from p in  db.properties
 join  c in  db.category on p.categoryId equals c.Id into cj
 from c in cj.DefaultIfEmpty()
 join  sc in  db.subCategory on on p.subCategoryId equals sc.Id into scj
 from sc in scj.DefaultIfEmpty()
 join  ssc in  db.secondSubCategory on on p.secondSubCategoryId equals ssc.Id into sscj
 from ssc in sscj.DefaultIfEmpty()
orderby  p.id descending
select new Property {
id= p.id 
 typeId=p.typeId,
 type=p.type,
 heatingId = p.heatingId,
 heating=p.heading, 
 categoryId = p.categoryId,
category =c,
subCategoryId= p.subCategoryId,
subCategory=sc,
secondSubCategoryId=p.secondSubCategoryId,
SecondSubCategory=ssc 
}).ToList();

我首先使用代码生成带有模型的数据库,然后使用一些数据进行测试。如果我不包括category and subCategory和secondSubCategory,结果与您的结果相同,但当我包括它们时,会有一个期望:

JsonException:检测到不支持的可能的对象循环。这可能是由于循环造成的,或者如果对象深度大于允许的最大深度32

然后我使用NewtonsoftJson来处理ReferenceLoopHandling问题

services.AddControllersWithViews()
    .AddNewtonsoftJson(options =>
     options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

然后,我可以从查询中获取类别、子类别和第二个子类别。

我首先使用代码生成模型数据库,然后使用一些数据进行测试。如果我不包括category and subCategory和secondSubCategory,结果与您的结果相同,但当我包括它们时,会有一个期望:

JsonException:检测到不支持的可能的对象循环。这可能是由于循环造成的,或者如果对象深度大于允许的最大深度32

然后我使用NewtonsoftJson来处理ReferenceLoopHandling问题

services.AddControllersWithViews()
    .AddNewtonsoftJson(options =>
     options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

然后,我可以从查询中获取类别、子类别和第二个子类别。

正如我从您的实体中获得的一样,您必须在数据库的设计中遵循层次结构原则。这是我的建议:

public class Property
{
    [Key]
    public int id { get; set; }    

    public int typeId { get; set; }
    public type type { get; set; }

    public int heatingId { get; set; }
    public heating heating { get; set; }

    public int? categoryId { get; set; }
    public category category { get; set; }
}

public class category
  {
    public int id { get; set; }
    public string category_Name { get; set; }

    public IList<subCategory> subCategories { get; set; }
    public Property Property { get; set; }

  }

public class subCategory
  {
    public int id { get; set; }
    public string subCategoryName { get; set; }

    public int CategoryId { get; set; }
    public category category { get; set; }

    public IList<SecondSubCategory> secondSubCategories { get; set; }
  }


public class SecondSubCategory
  {
    public int id { get; set; }
    public string secondCategoryName { get; set; }

    public int subCategoryId { get; set; }
    public subCategory subCategory { get; set; }
  }

正如我从您的实体中了解到的,在设计数据库时,您必须遵循层次结构原则。这是我的建议:

public class Property
{
    [Key]
    public int id { get; set; }    

    public int typeId { get; set; }
    public type type { get; set; }

    public int heatingId { get; set; }
    public heating heating { get; set; }

    public int? categoryId { get; set; }
    public category category { get; set; }
}

public class category
  {
    public int id { get; set; }
    public string category_Name { get; set; }

    public IList<subCategory> subCategories { get; set; }
    public Property Property { get; set; }

  }

public class subCategory
  {
    public int id { get; set; }
    public string subCategoryName { get; set; }

    public int CategoryId { get; set; }
    public category category { get; set; }

    public IList<SecondSubCategory> secondSubCategories { get; set; }
  }


public class SecondSubCategory
  {
    public int id { get; set; }
    public string secondCategoryName { get; set; }

    public int subCategoryId { get; set; }
    public subCategory subCategory { get; set; }
  }

查询中
.Include(cat=>cat.category)
的目的是什么?可以显示类别或子类别吗class@atiyar目的是从与属性相关的类别中获取数据,但您已经有了
。包含(s=>s.category)
。@Sergey
公共类类别{public int id{get;set;}公共字符串类别{u Name{get;set;}公共IList子类别{get;set;}公共属性属性{get;set;}}
包含的目的是什么(cat=>cat.category)在查询中?您可以显示类别或子类别吗class@atiyar目的是从与属性相关的类别中获取数据,但您已经有了
.Include(s=>s.category)
。@Sergey
公共类类别{public int id{get;set;}公共字符串类别{u Name{get;set;}公共IList子类别{get;set;}公共属性{get;set;}}
谢谢。。。。我发布子类只是要注意:属性必须有subCategoryId和secondSubCategoryId,因此我无法将它们从表中删除是的,您仍然可以保留所有这些属性,但它们只是额外的计算属性,不能用于包含。您必须手动分配它们。谢谢。。。。我发布子类只是要注意:属性必须有subCategoryId和secondSubCategoryId,因此我无法将它们从表中删除是的,您仍然可以保留所有这些属性,但它们只是额外的计算属性,不能用于包含。您必须手动分配它们。