2017-10-18 46 views
1

我想要做一个选择所有从单个表中获取三列,然后简单地使用结果作为数组。没有一个循环的代价。Silverstripe 3.5 - 如何查询特定的列并返回一个数组

我已经尝试了本使用ORM方法:

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

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

所以,我想这一点使用的SQLQuery来代替:

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

现在,这可以让我选择三个字段,但据我所知,有没有方法可以返回该查询像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 
     ) 
+0

结帐http://api.silverstripe.org/en/3.1/class-DataList。html#_setQueriedColumns –

+0

谢谢。我确实尝试过,但似乎没有按预期工作。请参阅编辑我的问题的细节。也许toNestedArray()忽略它? – Aaryn

+1

我很确定,当使用ORM时,总是输出数据对象系统字段。这些是ClassName,LastEdited,ID,Created。 'setQueriedColumns'然后允许你选择你添加到你的数据对象模型的字段。如果你只需要字段ID,Name,ParentID,你将需要使用sql查询,就像你在下面的回答中所做的那样。 –

回答

0

所以我决定这是一个过度依赖现有的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 
+0

我建议您在原始数据库查询上使用SQLSelect。它将确保与不同的RDBM兼容并降低注入攻击的风险。 – bummzack

+0

好主意。谢谢。 – Aaryn

2

按照API DocssetQueriedColumns()是你的朋友:

从你的问题我假设数据对象要查询被称为City,所以我们需要用它来从数据库中获取所有城市:

City::get(); 

这将返回一个DataList并在需要时查询数据库。到目前为止,您的数据库并不知道任何您想要的数据。那么让我们对它进行优化,按“名称”ASC对其进行排序。我喜欢数组要多得多,恕我直言,这是更易于阅读,如果你需要排序对第二行,只需将其添加到阵列中:

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

现在,你想要的,因为某些原因,只是一些列背部。因为我不知道是什么的数据库字段的数据对象City了,我以为你只是想“名称”和“ZIP”:

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

这限制了查询栏,你可以添加toNestedArray()获取数据出来的一个纯粹的老式阵列。这可能对将数据传递给API有用,但也许最好留下对象并在代码中使用城市特定的逻辑。

+0

对不起,我应该提到我看了setQueriedCoumns。我认为这不相关。似乎没有达到这个目的 $ cities = City :: get() - > sort(['Name'=>'ASC']) - > setQueriedColumns(['ID','Name']); Debug :: dump($ cities-> toNestedArray()); 输出表 – Aaryn

+0

中的所有字段,您可以通过向DataList添加' - > sql()'来查看生成的查询。我的猜测是,它首先减少了查询,但是当你运行'toNestedArray()'laster时,它会获取其他列。 – wmk

+0

Na我实际测试了一个循环而不是使用toNestedArray(),所有字段都在那里。不知道为什么setQueriedColumns似乎没有做它说的。在我的情况下,它不。 – Aaryn

相关问题