如何在API回复中隐藏数据库查询中的项目?

问题描述 投票:1回答:1

我目前正在使用带有EF的MVC来使用一个带有API查询SQL数据库的小型服务器。但是在API回复中我无法隐藏一些参数。

主要对象

public class AssetItem
{
   [Key]
   public Int32 AssetId { get; set; }
   public String AssetName { get; set; }

   public int OdForeignKey { get; set; }

   [ForeignKey("OdForeignKey")]
   public OperationalDataItem OperationalDataItem { get; set; }
}

另一个:

public class OperationalDataItem
{
   [Key]
   public Int32 OperationalDataId { get; set; }
   public String Comunity { get; set; }

   public List<AssetItem> AssetItems { get; set; }
}

从我读过的,这应该没问题,我也设置了上下文:

public AssetContext(DbContextOptions<AssetContext> options) : base(options)
{}

public DbSet<AssetItem> AssetItems { get; set; }
public DbSet<OperationalDataItem> OperationalDataItems { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<AssetItem>().HasOne(p => 
  p.OperationalDataItem).WithMany(b => b.AssetItems).HasForeignKey(p => 
  p.OdForeignKey);
}

并且在program.cs中播种

context.AssetItems.Add( 
  new AssetItem { AssetName = "Test test", OdForeignKey = 1, 
         OperationalDataItem  = 
            new OperationalDataItem {Comunity = "Comunity1" }});

所以调用API会导致:

{ "assetId":3,
  "assetName":"Test test",
  "odForeignKey":1,
  "operationalDataItem":null }

从我读到的这是因为延迟加载,我如何隐藏结果operationalDataItem?

如果不可能,我当然会尝试查询它并将其还给它,它给出了类似的东西:

{ "assetId":3,
  "assetName":"Test test",
  "odForeignKey":1,
  "operationalDataItem":
           { "operationalDataId":1,
             "comunity":"Comunity1",
             "assetItems":[

但在这种情况下,我想在FE的回复中隐藏“assetsItems”。我该如何隐藏这些参数?

API非常简单,只是一个示例代码:

var todoItem = await _context.AssetItems.FindAsync((Int32)id);
var item = _context.OperationalDataItems.Find((Int32)todoItem.OdForeignKey);
todoItem.OperationalDataItem = item;
return todoItem
c# asp.net-mvc entity-framework ef-code-first code-first
1个回答
0
投票

如果要从数据库中获取数据,但只想获取某些属性,请使用“选择”。通常这比使用Find更有效,因为您只会传输实际计划使用的数据。

要获取具有主键assetItemId的assetItem的某些属性:

var result = dbContext.AssetItems
    .Where(assetItem => assetItem.AssetItmId = assetItemId)
    .Select(assetItem => new
    {
        // Select only the properties that you plan to use
        Id = assetItem.AssertItemId,
        Name = assetItem.Name,

        OperationalData = new
        {
            // again, select only the properties that you plan to use
            Id = assetItem.OperationalData.OperationalDataId,
            Community = assetItem.OperationalData.Community,
        },
    })
    .FirstOrDefault();

或者反过来说:

获取所有(或一些)OperationalDataItem的几个属​​性,每个属性都包含其所有(或部分)AssetItem的一些属性:

var result = dbContext.OperqationalDataItems
    .Where(operationalDataItem => ...)           // only if you don't want all
    .Select(operationalDataItem => new
    {
         Id = operationalDataItem.Id, 
         Community = operationalDataItem.Community

         AssetItems = operationalDataItem.AssetItems
            .Where(assetItem => ...)            // only if you don't want all its assetItems
            .Select(assetItem => new
            {
                // Select only the properties you plan to use:
                Id = assetItem.Id,
                ...

                // not useful: you know the value of the foreign key:
                // OperationalDataId = assetItem.OperationalDataId,
            })
            .ToList();
    })
    .ToList();      // or: FirstOrDefault if you expect only one element

实体框架知道您的一对多关系,并且足够聪明,可以知道查询需要哪个(组)连接。

有些方面的评论

你已经宣布你的多关系是List<AssetItem>。你确定operationalDataItem.AssetItems[4]有明确的含义吗?坚持entity framework code first conventions不是更好吗?这也将消除对大多数属性和/或流畅API的需求

public class OperationalDataItem
{
   public int Id { get; set; }
   public String Comunity { get; set; }
   ...

   // Every OperationalDataItem has zero or more AssetItems (one-to-many)
   public virtual ICollection<AssetItem> AssetItems { get; set; }
}

public class AssetItem
{
    public int Id { get; set; }
    public String Name { get; set; }
    ...

    // every AssetItem belongs to exactly one OperationalDataItem, using foreign key
    public int OperationDataItemId { get; set; }
    public virtual OperationalDataItem OperationalDataItem { get; set; }
}

在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多,多对多)

因为我坚持惯例,所以不需要属性或流畅的API。实体框架能够检测一对多关系以及主键和外键。只有当我对列的名称或类型不满意时,我才需要流畅的API。

© www.soinside.com 2019 - 2024. All rights reserved.