Поскольку ваши столбцы и фильтры динамические, вам может помочь библиотека Dynamic LINQ
NuGet: https://www.nuget.org/packages/System.Linq.Dynamic/
Doc: http://dynamiclinq.azurewebsites.net/
using System.Linq.Dynamic; //Import the Dynamic LINQ library
//The standard way, which requires compile-time knowledge
//of the data model
var result = myQuery
.Where(x => x.Field1 == "SomeValue")
.Select(x => new { x.Field1, x.Field2 });
//The Dynamic LINQ way, which lets you do the same thing
//without knowing the data model before hand
var result = myQuery
.Where("Field1=\"SomeValue\"")
.Select("new (Field1, Field2)");
Другое решение - использовать Eval Expression.NET , который позволяет вам динамически оценивать код c # во время выполнения.
using (var ctx = new TestContext())
{
var query = ctx.Entity_Basics;
var list = Eval.Execute(@"
q.Where(x => x.ColumnInt < 10)
.Select(x => new { x.ID, x.ColumnInt })
.ToList();", new { q = query });
}
Отказ от ответственности: Я являюсь владельцем проекта Eval Expression.NET
Редактировать: ответьте комментарий
Будьте осторожны, тип значения параметра должен быть совместим с типом свойства. Например, если свойство «Ранг» является INT, будет работать только тип, совместимый с INT (не строка).
Очевидно, вам нужно будет реорганизовать этот метод, чтобы сделать его более подходящим для вашего приложения. Но, как вы можете видеть, вы можете легко использовать даже метод async из Entity Framework.
Если вы также настроили select также (тип возврата), вам может понадобиться либо получить результат async с помощью отражения, либо вместо этого использовать ExecuteAsync с ToList ().
public async Task> DynamicWhereAsync(CancellationToken cancellationToken = default(CancellationToken))
{
// Register async extension method from entity framework (this should be done in the global.asax or STAThread method
// Only Enumerable && Queryable extension methods exists by default
EvalManager.DefaultContext.RegisterExtensionMethod(typeof(QueryableExtensions));
// GET your criteria
var tuples = new List>();
tuples.Add(new Tuple("Specialty", "Basket Weaving"));
tuples.Add(new Tuple("Rank", "12"));
// BUILD your where clause
var where = string.Join(" && ", tuples.Select(tuple => string.Concat("x.", tuple.Item1, " > p", tuple.Item1)));
// BUILD your parameters
var parameters = new Dictionary();
tuples.ForEach(x => parameters.Add("p" + x.Item1, x.Item2));
using (var ctx = new TestContext())
{
var query = ctx.Entity_Basics;
// ADD the current query && cancellationToken as parameter
parameters.Add("q", query);
parameters.Add("token", cancellationToken);
// GET the task
var task = (Task>)Eval.Execute("q.Where(x => " + where + ").ToListAsync(token)", parameters);
// AWAIT the task
var result = await task.ConfigureAwait(false);
return result;
}
}
Изображенный я отправил бы то, что я наконец пошел с - WinSCP - http://winscp.net
Подключения через GUI к серверу SFTP + поддерживают синхронизацию Local/Remote/Both + scriptable с интерфейсом командной строки/пакета.
Вы могли настроить совместно используемые папки по безопасной VPN с Hamachi, затем использовать приложение синхронизации папки для синхронизации их.
Походит на типичный случай для использования FolderShare.
Я не думаю, что Вы могли пойти мимо rsync. Это быстро, надежно и когда вместе с SSH (который является вашим требованием), безопасный. Это также Свободно!
Если Вы хотите некоторую интеграцию со своими системами управления версиями, проверяете Унисон.
Существуют также коммерческие альтернативы, такие как InstantSync.
Я использую SVN. Это работает (я думаю) по SSH и SSL.
Полное управление версиями, синхронизация файла, чему не должно нравиться?
Я рекомендовал бы rdiff-резервное-копирование. Это поддерживает возрастающие резервные копии по SSH и является бесплатным и проверенным решением. Будучи возрастающим, это также предоставляет доступ к файлам, которые были удалены или к более старым версиям измененных файлов.
+1 для рекомендации Chris. Это точно, для чего я использую FolderShare, сохраняет папки в синхронизации через 3 ПК, запускающие Windows и 2 Mac рабочий OS X.