Во многом благодаря ответу @ anthony на подобный вопрос здесь , у меня, кажется, есть некоторый рабочий код ...
// Prepare Article URLs list as an array
$article_urls = array();
// Call Airtable records in pages of 100 max
do {
// Offset is either inherited from last page's results, or is nothing
$offset = $articles['offset'] ?: "";
// Make get request, store result in array
$articles = get_airtable_records($offset);
// For each URL found in Airtable
foreach($articles['records'] as $record){
$url = $record['fields']['Published url'];
// Add to our array list
if (!empty($url)) {
array_push($article_urls, $url);
}
}
} while(!empty($articles['offset'])); // If there's an offset value (ie. starting record of next page), do again
// Output URL list for check
echo '';
print_r($article_urls);
echo '
';
Объяснение выглядит следующим образом:
Используйте петлю do
while
. В начале этого установите offset
либо значение, унаследованное от предыдущего запуска, либо ничего.
Моя get_airtable_records
функция уже ограничивала присутствие или отсутствие offset
в вызове API следующим образом, который добавляет строку запроса offset
к URL-адресу для следующего вызова API, если таковой имеется. .
if (!empty($offset)) {
$q_offset = '&offset='.$offset;
}
Я проверил это, и он дал мне все 137 результатов с двух страниц в моем массиве $article_urls
. Я не тестировал его с более чем двумя страницами результатов.
В основном, нет.
EntitySet<T>
класс имеет внутреннее Source
свойство, которое присвоено контекстом данных, который является, как это достигает данные, по запросу. Однако нет ничего подобного для самих классов данных.
Однако я полагаю, что Платформа Объекта имеет намного больше доступа к этому, за счет вынужденной иерархии объектов.
В отличие от Платформы Объекта, LINQ-SQL (дизайном) может использоваться с регулярными, неосведомленными персистентности классами - таким образом, это не предполагает, что имеет доступ к этому типу данных.
Класс Объекта не должен знать о контексте данных как его просто, отображение таблицы, но контекста данных имеет знание всех объектов и свойств соединения
Вы можете связаться с дочерней таблицей через родительский класс объекта из-за связи сущностей а не через контекст данных
Класс контекста данных будет использоваться в конце, где объекты используются, я не вижу потребность в объектах для знания о контексте,
Если можно сказать определенному сценарию, что мы можем попробовать другой подход.
Я точно знаю, что вы имеете в виду. Предполагается, что мы должны выполнять наши вычисления / проверку в частичном классе сущности, но если у сущности нет доступа к текстовому тексту данных, то сколько мы можем сделать? Например, в моем объекте SalesOrder всякий раз, когда адрес «Отправлять» изменяется, SalesOrder должен запросить базу данных, чтобы выяснить, применяется ли налог к этому состоянию / почтовому индексу. Я боролся с этим некоторое время, но сегодня я сломался и пошел с уродливым методом, но пока все хорошо. По сути, все, что я делаю, - это создаю свойство «Context» в моем частичном классе и задаю его с помощью datacontext при создании сущности.
Partial Class SalesOrder
Private moContext As L2S_SalesOrdersDataContext
Friend Property Context() As L2S_SalesOrdersDataContext
Get
Return moContext
End Get
Set(ByVal value As L2S_SalesOrdersDataContext)
moContext = value
End Set
End Property
...
YMMV, особенно если вы отсоединяете свои сущности.
В принципе, вы можете сделать это с помощью небольшого хака. DataCOntext прикрепляет StandardChangeTracker к вашей сущности:
DataContext context = null; object changeTracker = (from i in o1.GetInvocationList() where i.Target.GetType().FullName == "System.Data.Linq.ChangeTracker+StandardChangeTracker" select i.Target).FirstOrDefault(); if (changeTracker != null) // DataCOntext tracks our changes through StandardChangeTracker { object services = Reflector.GetFieldValue(changeTracker, "services"); context = (DataContext)Reflector.GetFieldValue(services, "context"); }
Where Reflector.GetFieldValue equals to
public static object GetFieldValue(object instance, string propertyName) { return instance.GetType().GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance); }
Мне только что пришлось сделать точно то же самое. Вот мое решение (хотя, возможно, это не лучший подход, но, по крайней мере, довольно элегантный):
Во-первых, создайте интерфейс для всех ваших сущностей, который будет наследоваться от INotifyPropertyChanging. Это используется для подключения некоторых методов расширения и сохранения раздельной реализации. В моем случае интерфейс называется ISandboxObject:
public interface ISandboxObject : INotifyPropertyChanging
{
// This is just a marker interface for Extension Methods
}
Затем создайте новый статический класс, который будет содержать метод расширения для получения DataContext. Это достигается путем поиска обработчика события на LINQ Change Tracker, прикрепленного к событию INotifyPropertyChanging.PropertyChanging. Как только мы нашли трекер изменений, мы можем получить DataContext оттуда:
/// <summary>
/// Obtain the DataContext providing this entity
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static DataContext GetContext(this ISandboxObject obj)
{
FieldInfo fEvent = obj.GetType().GetField("PropertyChanging", BindingFlags.NonPublic | BindingFlags.Instance);
MulticastDelegate dEvent = (MulticastDelegate)fEvent.GetValue(obj);
Delegate[] onChangingHandlers = dEvent.GetInvocationList();
// Obtain the ChangeTracker
foreach (Delegate handler in onChangingHandlers)
{
if (handler.Target.GetType().Name == "StandardChangeTracker")
{
// Obtain the 'services' private field of the 'tracker'
object tracker = handler.Target;
object services = tracker.GetType().GetField("services", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(tracker);
// Get the Context
DataContext context = services.GetType().GetProperty("Context").GetValue(services, null) as DataContext;
return context;
}
}
// Not found
throw new Exception("Error reflecting object");
}
Теперь у вас есть хороший метод расширения, который предоставит вам DataContext из любого объекта, реализующего ISandboxObject. Пожалуйста, сделайте дополнительную проверку ошибок, прежде чем использовать его в гневе!