Сначала просто уточнить :) .. Вы используете SharePoint on-prem, верно?Таким образом, мы можем использовать решения Farm.Если да, то я бы разрешил этот случай с помощью следующего решения.Я хотел бы разработать SPJob (задание таймера SharePoint).Он может быть включен только в решение Farm.В основном это выглядит так:
- создайте проект Farm в решении
- добавьте класс, который наследуется от SPJobDefinition, и поместите свою логику в метод Execute, который необходимо переопределить (в этом методе создайтестандартное соединение SQL и запросите эту таблицу из базы данных mySQL, затем сравните с вашим SPList и выполните работу :)) (также, возможно, здесь хорошим подходом было бы сохранить некоторые учетные данные для этой строки соединения в каком-то SPList на каком-либо сайте конфигурации или где-то еще)..не жестко его закодировать;)) Например,
public class CustomJob : SPJobDefinition
{
public CustomJob() : base() { }
public CustomJob(string jobName, SPService service) : base(jobName, service, null, SPJobLockType.None)
{
this.Title = jobName;
}
public CustomJob(string jobName, SPWebApplication webapp) : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
this.Title = jobName;
}
public override void Execute(Guid targetInstanceId)
{
SPWebApplication webApp = this.Parent as SPWebApplication;
try
{
// Your logic here
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("CustomJob - Execute", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
}
добавьте новую функцию в решение, которое называется webApplication, и добавьте получатель событий к этой функции при активной функции зарегистрируйте задание таймера (не забудьте удалить его при деактивированной :))
public class Feature2EventReceiver : SPFeatureReceiver
{
const string JobName = "CustomJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
// add job
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
CreateJob(parentWebApp);
});
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("CustomJob-FeatureActivated", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
// delete job
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("CustomJob-FeatureDeactivating", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
}
private bool CreateJob(SPWebApplication site)
{
bool jobCreated = false;
try
{
// schedule job for once a day
CustomJob job = new CustomJob(JobName, site);
SPDailySchedule schedule = new SPDailySchedule();
schedule.BeginHour = 0;
schedule.EndHour = 1;
job.Schedule = schedule;
job.Update();
}
catch (Exception)
{
return jobCreated;
}
return jobCreated;
}
public bool DeleteExistingJob(string jobName, SPWebApplication site)
{
bool jobDeleted = false;
try
{
foreach (SPJobDefinition job in site.JobDefinitions)
{
if (job.Name == jobName)
{
job.Delete();
jobDeleted = true;
}
}
}
catch (Exception)
{
return jobDeleted;
}
return jobDeleted;
}
}
развертывание и активация вашей функции в веб-приложении (я думаю, что лучше всего настроить работу так, чтобы она выполнялась каждый день или каждый час)
- хорошая статья с примером того, какдля этого все можно найти здесь (я знаю, что статья для SP 2010, но она будет работать так же для 2013, 2016 и, вероятно, также 2019 (с этой предварительной версией у меня не так многоexp):)
- другая статья с таким же решением здесь (это для SP 2013)
** Обновление **
для SharePoint Online вышеупомянутое решение не будет работать, так как это решение для фермы.В Online решение как всегда что-то «внешнее» :).Наверняка у вас уже есть какой-то сервер, на котором вы храните решения для SP онлайн (например, приложения SP, размещенные у провайдера и т. Д.).Мой подход заключается в разработке простого консольного приложения на C #.Сначала в этом приложении выполните SQL-соединение с mySql и запросите таблицу, чтобы получить данные. Затем выполните CSOM-запрос SharePoint List, чтобы выполнить сравнение.что-то вроде этого
using (var clientContext = new ClientContext("url"))
{
CamlQuery camlQuery = new CamlQuery();
string query = "add some query here";
camlQuery.ViewXml = query;
collListItem = list.GetItems(camlQuery);
clientContext.Load(collListItem, items => items.Include( item => item["Title"], item => .... // add other columns You need here);
clientContext.ExecuteQuery();
if (collListItem.Count > 0)
{
// Your code here :)
}
}
Также имейте в виду, что вы можете запустить CSOM с учетными данными другого пользователя (например, администратором), указав сетевые учетные данные следующим образом:
NetworkCredential _myCredentials = new NetworkCredential("user", "password", "companydomain");
Также, пожалуйста,знать о пороге ... в CSOM Вы всегда можете использовать разбитый на страницы запрос, если сначала вы получили 5000 элементов, затем до 5000 и т. д. до тех пор, пока коллекция не станет пустой :).После того, как вы вручную запустите это консольное приложение, чтобы убедиться, что оно работает правильно, просто добавьте это консольное приложение в планировщик задач на этом сервере в качестве новой задачи в библиотеке задач.Также там Вы можете указать время запуска, например, запускать каждый час или день и т. Д. здесь - хорошая статья о переполнении стека, как добавить такую задачу
.. Надеюсь, теперь ответ лучшедля вашей среды:)