Linq to Salesforce «поставщик SQL»

Итак, у меня есть этот новый проект. Моя компания использует облако SalesForce.com для хранения информации о повседневных операциях. Моя работа состоит в том, чтобы написать новое приложение, которое, среди прочего, будет более плавно интегрировать операции CRUD с этими данными с существующими внутренними функциями приложения.

Ядром Salesforce WSDL API является набор "query ()" "веб-методы, которые принимают команду запроса в виде строки. Синтаксис запроса - SQL-ish, но не совсем (они называют это SOQL). Я не фанат «волшебных строк», поэтому я хотел бы использовать Linq в базе кода и преобразовывать IQueryable в запрос SOQL, который мне нужен в оболочке для службы. Это, конечно, возможно (L2E, L2Sql), но я хотел бы знать, есть ли ярлык, потому что, если я скажу, что на то, чтобы свернуть мой собственный, уйдет больше дня или двух, я буду "поощрен" найти другой метод (скорее всего, метод для каждого общего запроса, который использовался в старых приложениях). Если мне удастся создать синтаксический анализатор SOQL общего назначения, мы сможем использовать его в нескольких других будущих приложениях, и я буду героем. Даже если я сделаю простой, поддерживающий только определенные структуры запросов, он будет иметь большое значение, позволив мне продолжить текущий проект в стиле Linq-y, и я смогу расширить его в свободное время.

Вот варианты, которые я вижу:

  • Поищите внимательнее для существующего провайдера Linq2SOQL (мой Google-fu подводит меня здесь, иначе его просто нет; единственная оболочка .NET упоминает Linq только как
  • Создайте синтаксический анализатор дерева выражений. Он должен поддерживать, по крайней мере, вызовы методов Select и Where, а также должен либо анализировать лямбда-выражения, либо манипулировать их телами методов, чтобы получить необходимые операции и проекции. Это кажется довольно сложной задачей, но, как я уже сказал, это, безусловно, возможно.
  • Оберните службу в Linq2Sql или аналогичный существующий поставщик Linq, который позволит мне извлечь достаточно близкую строку запроса, отполировать ее и передать это к сервису. Их должно быть несколько десятков (хотя ни одного, который просто не появляется, AFAIK).
  • Вызов Expression.ToString () (или Expression.DebugView), и манипулируйте этой строкой для создания запроса SOQL. Он будет хрупким, уродливым (за кулисами), и он будет поддерживать только то, что я ищу, но он предоставит элементарный перевод, который позволит мне двигаться дальше.

Что делать вы думаете? Создание парсера Linq - это больше, чем двухдневная задача для одного человека? Может ли это сделать сложное решение с участием существующего поставщика Linq? Было бы ужасно разрезать строку выражения и таким образом построить мой запрос?

РЕДАКТИРОВАТЬ: Спасибо Кирку за обоснование. Я еще раз посмотрел на то, что мне нужно было бы сделать даже для базового парсера SOQL, и это выходит за рамки моих возможностей получить рабочий код приложения, написанный по любому возможному графику. Например, Мне нужно создать список выбора либо из лямбда-выражения метода Select (), либо из списка по умолчанию из всех известных столбцов моего объекта WSDL, задача, о которой я даже не думал (я больше сосредоточился на синтаксическом анализе Where). Я уверен, что есть много других «неизвестных неизвестностей», которые могут превратить это в большое дело. Я нашел несколько ссылок, которые показывают основы написания провайдера Linq, и, хотя все они пытаются упростить его, сейчас это просто невозможно с точки зрения времени. На данный момент я структурирую свой репозиторий, используя именованные методы, которые инкапсулируют именованные запросы (постоянный класс форматируемых строк запроса должен уменьшить количество хлопот в обслуживании). Не идеально, но гораздо более осуществимо. Если и когда провайдер Linq2SOQL начнет работу, будь то собственный или открытый исходный код, мы сможем провести рефакторинг.

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class EqualToPropertyAttribute : ValidationAttribute
    {
        public string CompareProperty { get; set; }

        public EqualToPropertyAttribute(string compareProperty)
        {
            CompareProperty = compareProperty;
            ErrorMessage = string.Format(Messages.EqualToError, compareProperty);
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            var property = properties.Find(CompareProperty, true);
            var comparePropertyValue = property.GetValue(value).ToString();

            return comparePropertyValue == value.ToString();
        }
    }

У меня есть класс модели представления, в котором есть все поля для формы регистрации, как показано ниже:

public class SignUpViewModel
    {
        [Required]
        [StringLength(100)]
        public string Username { get; set; }

        [Required]
        [Password]
        public string Password { get; set; }

        [Required]
        [DisplayText("RetypePassword")]
        [EqualToProperty("Password")]
        public string RetypePassword { get; set; }

        [Required]
        [StringLength(50)]
        [DisplayText("FirstName")]
        public string FirstName { get; set; }

        [Required]
        [StringLength(100)]
        [DisplayText("LastName")]
        public string LastName { get; set; }

        [Required]
        [DisplayText("SecurityQuestion")]
        public int SecurityQuestionID { get; set; }

        public IEnumerable<SelectListItem> SecurityQuestions { get; set; }

        [Required]
        [StringLength(50)]
        public string Answer { get; set; }
}

Ниже приведен код моего контроллера:

public virtual ActionResult Index()
    {
        var signUpViewModel = new SignUpViewModel();

        signUpViewModel.SecurityQuestions = new SelectList(questionRepository.GetAll(),"SecurityQuestionID", "Question");
        return View(signUpViewModel);
    }

        [HttpPost]
        public virtual ActionResult Index(SignUpViewModel viewModel)
        {
            // Code to save values to database
        }

Когда я ввожу значения формы и нажимаю «Отправить», строка кода пытается получить дескриптор свойства var property = properties.Find (CompareProperty, true); возвращает значение null. Может ли кто-нибудь помочь мне понять, почему это происходит?

8
задан Kumar 6 November 2010 в 18:47
поделиться