Web API 2.返回说明而不是Int Join / Include吗?

时间:2018-11-06 17:12:59

标签: c# entity-framework linq join

嗨,我对API的Entity框架和Linq还是很陌生。

在做一些我可以在SQL和Web表单中轻松完成的事情时,我遇到了麻烦。

我首先使用了EF数据库(在我未创建且无法更改的数据库上) 将前两张桌子带回3张桌子:

  1. 模型(fc_models)列表,其字段包含一个int(ModelSeq)作为主键

  2. 链接到第一张表中的模型的零件(fc_linkedParts)列表。它具有相同的字段(ModelSeq)设置为外键,而ModelSeq和Partnum设置为主键。

  3. 第三个表是零件类的列表,它包含一个ClassId字段和一个Description字段。就数据库而言,该表与FC_linked部分之间没有链接,但是,当然,在SQL中,我可以简单地在此表和fc_linkedparts表中的ClassId上联接

我有实体框架创建的数据模型。

namespace DBF_Models
{
using System;
using System.Collections.Generic;

public partial class fc_Models
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public fc_Models()
    {
        this.fc_LinkParts = new HashSet<fc_LinkParts>();
    }

    public int ModelSeq { get; set; }
    public string ModelId { get; set; }
    public string ModelDesc { get; set; }
    public string Manufacturer { get; set; }
    public string Category { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<fc_LinkParts> fc_LinkParts { get; set; }
    }
}


namespace DBF_Models
{
using System;
using System.Collections.Generic;

public partial class fc_LinkParts
    {
    public int ModelSeq { get; set; }
    public string PartNum { get; set; }
    public string PartDescription { get; set; }
    public string Manufacturer { get; set; }
    public string PartClass { get; set; }

    public virtual fc_Models fc_Models { get; set; }
    }
}



namespace DBF_Models
{
using System;
using System.Collections.Generic;

public partial class PartClass
   {
    public string Company { get; set; }
    public string ClassID { get; set; }
    public string Description { get; set; }
    public string BuyerID { get; set; }
    public bool RcvInspectionReq { get; set; }
    public string CommodityCode { get; set; }
    public bool AvailForReq { get; set; }
    public decimal MtlBurRate { get; set; }
    public bool SplitPOLine { get; set; }
    public string NegQtyAction { get; set; }
    public string PurchCode { get; set; }
    public bool ConsolidatedPurchasing { get; set; }
    public bool GlobalPartClass { get; set; }
    public bool GlobalLock { get; set; }
    public byte[] SysRevID { get; set; }
    public System.Guid SysRowID { get; set; }
   }
}

我不需要表中的所有信息,所以我创建了一些DTO (此外,我正在寻找一个解决方案,其问题与当时的情况类似)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DBF_Models.Models
{
public class ModelDto
{
    public int ModelSeq { get; set; }
    public string ModelId { get; set; }
    public string ModelDescription { get; set; }
    public string Manufacturer { get; set; }
    public string EntityType { get; set; }
    public IEnumerable<PartDto> PartList { get; set; }
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DBF_Models.Models
{
    public class PartDto
{
    public string SKU { get; set; }
    public string Description { get; set; }
    public int ModelId { get; set; }

    public string EntityType = "Part";
    public string Manufacturer { get; set; }
    public string Class { get; set; }

}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;

namespace DBF_Models.Models
{
public class PartClassDto
{
    public string ClassId { get; set; }
    public string ClassDescription { get; set; }
}
}

用于在嵌套Json中获取数据的代码

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Web.Http;
using System.Web.Http.Description;
using System.Web.UI.WebControls;
using DBF_Models;
using DBF_Models.Models;



namespace DBF_Models.Controllers
{
public class LinkedPartsController : ApiController
{
    private ErpDevReplicationEntities db = new ErpDevReplicationEntities();

    // GET: api/sp_fc_ModelList_test_Result
    [Route("api/LinkedParts/All")]
    public Object GetAll()
    {

        var models = db
            .fc_Models
            .Include("fc_LinkParts")
            .Select(t => new ModelDto()
            {

                ModelSeq = t.ModelSeq,
                ModelId = t.ModelId,
                EntityType = "Model",
                ModelDescription = t.ModelDesc,
                Manufacturer = t.Manufacturer,
                PartList = t.fc_LinkParts.Select(p => new PartDto()
                {

                    EntityType = "Part",
                    ModelId = p.ModelSeq,
                    SKU = p.PartNum,
                    Description = p.PartDescription,
                    Manufacturer = p.Manufacturer,
                    Class = p.PartClass
                })
            });




        return models;
    }

输出

[
{
    "ModelSeq": 3020,
    "ModelId": "ACW                 ",
    "ModelDescription": "ACW                 ",
    "Manufacturer": "Hobart Manufacturing Ltd",
    "EntityType": "Model",
    "PartList": [
        {
            "EntityType": "Part",
            "SKU": "HOB01-240051-11     ",
            "Description": "FILTER                        ",
            "ModelId": 3020,
            "Manufacturer": "Hobart Manufacturing Ltd",
            "Class": "600"
        },
        {
            "EntityType": "Part",
            "SKU": "HOB104329           ",
            "Description": "MECHANICAL SEAL ASSY 5/8\"     ",
            "ModelId": 3020,
            "Manufacturer": "Hobart Manufacturing Ltd",
            "Class": "186"
        },
        {
            "EntityType": "Part",
            "SKU": "HOB122674           ",
            "Description": "FLOAT ASSEMBLY                ",
            "ModelId": 3020,
            "Manufacturer": "Hobart Manufacturing Ltd",
            "Class": "201"
        },......

TLDR; 显然,这仅使用表1(fc_models)和表2(fc_LinkParts) 我需要实现的是PartClass表或DTO中的链接,而不是像Int中那样显示描述的输出类。

期望的outpuy

[
{
    "ModelSeq": 3020,
    "ModelId": "ACW                 ",
    "ModelDescription": "ACW                 ",
    "Manufacturer": "Hobart Manufacturing Ltd",
    "EntityType": "Model",
    "PartList": [
        {
            "EntityType": "Part",
            "SKU": "HOB01-240051-11     ",
            "Description": "FILTER                        ",
            "ModelId": 3020,
            "Manufacturer": "Hobart Manufacturing Ltd",
            "Class": "Dishwasher"
        },....

我敢肯定,解决方案将比写这篇文章简单且花费更少的时间,但是我对EF / Linq代码感到困惑。

感谢阅读

解决方案:有效,但不确定最佳方法

因此在penleychan的帮助下 我尝试使用对我来说有意义的Join,这是我在SQL中要做的事情,但我只是无法弄清楚语法或将其放置在何处。 如果是SQL,我会放在这里

 PartList = t.fc_LinkParts.Select(p => new PartDto()
                {

                    EntityType = "Part",
                    ModelId = p.ModelSeq,
                    SKU = p.PartNum,
                    Description = p.PartDescription,
                    Manufacturer = p.Manufacturer,
                    Class = (from d in db.PartClasses
                        where d.ClassID == p.PartClass
                        select d.Description).FirstOrDefault()
                }) "JOIN WOULD GO HERE"

但是无法弄清楚能够访问创建连接所需的所有字段的语法。

因此,我想出的解决方案是作为SQL子查询工作的。我不确定,因为我不知道Linq转换为什么SQL。

    // GET: api/sp_fc_ModelList_test_Result
    [Route("api/LinkedParts/All")]
    public Object GetAll()
    {

        var models = db
            .fc_Models
            .Include("fc_LinkParts")
            .Select(t => new ModelDto()
            {

                ModelSeq = t.ModelSeq,
                ModelId = t.ModelId,
                EntityType = "Model",
                ModelDescription = t.ModelDesc,
                Manufacturer = t.Manufacturer,
                PartList = t.fc_LinkParts.Select(p => new PartDto()
                {

                    EntityType = "Part",
                    ModelId = p.ModelSeq,
                    SKU = p.PartNum,
                    Description = p.PartDescription,
                    Manufacturer = p.Manufacturer,
                    Class = (from d in db.PartClasses
                        where d.ClassID == p.PartClass
                        select d.Description).FirstOrDefault()
                })
            });




        return models;
    }

TLDR; 它有效,但是有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

解决方案:有效,但不确定最佳方法

因此在penleychan的帮助下 我尝试使用对我来说有意义的Join,这是我在SQL中要做的事情,但我只是无法弄清楚语法或将其放置在何处。 如果是SQL,我会放在这里

 PartList = t.fc_LinkParts.Select(p => new PartDto()
                {

                    EntityType = "Part",
                    ModelId = p.ModelSeq,
                    SKU = p.PartNum,
                    Description = p.PartDescription,
                    Manufacturer = p.Manufacturer,
                    Class = (from d in db.PartClasses
                        where d.ClassID == p.PartClass
                        select d.Description).FirstOrDefault()
                }) "JOIN WOULD GO HERE"

但是无法弄清楚能够访问创建连接所需的所有字段的语法。

因此,我想出的解决方案是作为SQL子查询工作的。我不确定,因为我不知道Linq转换为什么SQL。

    // GET: api/sp_fc_ModelList_test_Result
    [Route("api/LinkedParts/All")]
    public Object GetAll()
    {

        var models = db
            .fc_Models
            .Include("fc_LinkParts")
            .Select(t => new ModelDto()
            {

                ModelSeq = t.ModelSeq,
                ModelId = t.ModelId,
                EntityType = "Model",
                ModelDescription = t.ModelDesc,
                Manufacturer = t.Manufacturer,
                PartList = t.fc_LinkParts.Select(p => new PartDto()
                {

                    EntityType = "Part",
                    ModelId = p.ModelSeq,
                    SKU = p.PartNum,
                    Description = p.PartDescription,
                    Manufacturer = p.Manufacturer,
                    Class = (from d in db.PartClasses
                        where d.ClassID == p.PartClass
                        select d.Description).FirstOrDefault()
                })
            });




        return models;
    }

TLDR; 它有效,但是有更好的方法吗?