Silverstripe 3.5 - 如何查询特定列和 return 数组

Silverstripe 3.5 - How to query for specific columns and return an array

我正在尝试执行 select all 以从单个 table 中获取三列,然后将结果用作数组。没有循环的费用。

我已经尝试过使用 ORM 方法:

DataObject::get('City')->sort('Name ASC')->toNestedArray();

这给了我一个完美的数组。但是我看不到只 return 我想要的列的方法。它 return 是所有列。这是一个问题,因为我正在 json 编码这个数组,因此数据包是它需要的 3 倍。

所以我尝试使用 SQLQuery 代替:

DB::query('SELECT "ID","Name","ParentID" FROM "City"');

现在这允许我 select 三个字段,但据我所知,没有方法 return 此查询作为数组,如 toNestedArray()

搜索过高低但没有合适的。有任何想法吗?

编辑:应该提到我已经尝试过 setQueriedColumns() 抱歉。这似乎不是我在这里做的事情。

$cities = AspireCity::get()->sort(['Name' =>  'ASC'])->setQueriedColumns(['ID', 'Name']);
Debug::dump($cities->toNestedArray());

输出:

Array
(
    [0] => Array
        (
            [ClassName] => City
            [LastEdited] => 2017-09-26 11:14:16
            [Name] => Acacia Bay
            [ID] => 70
            [RecordClassName] => City
            [Created] => 
            [ParentID] => 9
        )

    [1] => Array
        (
            [ClassName] => City
            [LastEdited] => 2017-09-26 11:14:16
            [Name] => Ahaura
            [ID] => 71
            [RecordClassName] => City
            [Created] => 
            [ParentID] => 9
        )

根据API DocssetQueriedColumns()是你的朋友:

根据你的问题,我假设你要查询的数据对象叫做 City,所以我们需要这个来从数据库中取出所有城市:

City::get();

这个returns一个DataList然后在需要的时候查询数据库。到目前为止,您的数据库并不知道您想要从中获取一些数据。因此,让我们对其进行细化,按 "Name" ASC 对其进行排序。我更喜欢数组语法,恕我直言,它更易于阅读,如果您需要对第二行进行排序,只需将其添加到数组中即可:

City::get()
    ->sort(['Name' =>  'ASC']);

出于某些原因,现在您只想返回一些专栏。因为我不知道你的 City DataObject 有哪些数据库字段,我假设你只想要 'Name' 和 'ZIP':

City::get()
    ->sort(['Name' =>  'ASC'])
    ->setQueriedColumns(['Name', 'ZIP']);

这限制了查询的列,您可以添加 toNestedArray() 以将数据作为纯复古数组输出。这可能有助于将数据传递给 API,但最好保留对象并在代码中使用特定于城市的逻辑。

所以我认为这是一个过度依赖现有 SS 辅助方法的案例。虽然 toNestedArray() 非常方便,但我对它的关注主要是基于我可以通过使用它来避免循环的想法。实际上,该方法当然是一个循环。所以我的担心真的是多余的。

最重要的目标是在查询时减少数据集。所以解决方案只关注这一点。

// Inject the default country/city/suburb data as vars so they can be easily filtered.
$location['countries'] = DB::query('SELECT "ID","Description" FROM "Country" ORDER BY "ID" ASC'); 
$location['cities'] = DB::query('SELECT "ID","Name","ParentID" FROM "City" ORDER BY "Name" ASC'); 
$location['suburbs'] = DB::query('SELECT "ID","Name","ParentID" FROM "Suburb" ORDER BY "Name" ASC');

$masterLocationArray = [];
foreach($location as $key => $data) {
    $locationArray = [];
    foreach($data as $item) {
        $locationArray[] = $item;
    }
    $masterLocationArray[$key] = $locationArray;
}

// $masterLocationArray is our filtered, tidy array. Do stuff with it