Web API 2. Вернуть описание вместо Int Присоединиться / Включить? - PullRequest
0 голосов
/ 06 ноября 2018

Привет, я довольно новичок в API-интерфейсе Entity и Linq.

И у меня возникли проблемы с тем, что я мог бы легко сделать в SQL и веб-формах.

Сначала я использовал базу данных EF (для базы данных, которую я не создал и не могу изменить) Чтобы вернуть 3 таблицы, первые две таблицы:

  1. Список моделей (fc_models) с полем, содержащим int (ModelSeq), который является первичным ключом

  2. Список деталей (fc_linkedParts), связанных с моделями в первой таблице. для него установлено то же поле (ModelSeq), что и для внешнего ключа, а ModelSeq и Partnum - для первичного ключа.

  3. Третья таблица представляет собой список классов Part, она содержит поле ClassId и поле Description. Что касается базы данных, то нет связи между этой таблицей и частями FC_linked, но, конечно, в SQL я могу просто присоединиться к ClassId как в этой таблице, так и в таблице fc_linkedparts

У меня есть свои модели данных, созданные структурой сущностей.

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, будет показано описание.

Желаемый выход

[
{
    "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.

Спасибо за чтение

Решение: работает, но не уверен, что это лучший способ

Так с помощью пенлейчан Я пытался использовать соединение, которое для меня имело смысл, и это было то, что я делал в 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. Я не уверен, так как не знаю, в какой SQL преобразован Linq.

    // 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 голосов
/ 07 ноября 2018

Решение: работает, но не уверен, что это лучший способ

Так с помощью пенлейчан Я пытался использовать соединение, которое для меня имело смысл, и это было то, что я делал в 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. Я не уверен, так как не знаю, в какой SQL преобразован Linq.

    // 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; Это работает, но есть ли лучший способ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...