Получение значений связанных объектов в конфигурационном веб-сервисе
Доброго времени суток! Коллеги, помогите пожалуйста с переводом запроса SQL на С# для использования в конфигурационном веб-сервисе. Необходимо через запрос к веб-сервису по ИНН контакта получать в ответе перечень Id заявок и Названий их статусов. SQL запрос выглядит так:
SELECT a.Id, s.Name
FROM dbo.Application a
INNER JOIN dbo.Contact c ON a.ContactId = c.Id
INNER JOIN dbo.AppStatus s ON a.StatusId = s.Id
WHERE c.INNN='1234567890'
Нравится
Сделал согласно информации в указанных статьях:
public string UsrGetAppInfoByINN(string INN) { // Результат по умолчанию. var result = ""; // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных. var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application"); // Добавление колонок в запрос. esqQuery.AddColumn("Id"); esqQuery.AddColumn("[AppStatus:Id:StatusId].Name"); esqQuery.AddColumn("[Contact:Id:ContactId].INN"); // Фильтрация данных запроса. var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN); esq.Filters.Add(esqFilter); // Получение результата запроса. string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); // Возвратить результат. return result;
При публикации получаю ошибки "The name 'esq' does not exist in current context в строках:
var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN); esq.Filters.Add(esqFilter);
esq.Filters.Add(esqFilter);
Так у Вас переменная называется esqQuery, а не esq.
Зверев Александр,
заменил esq на esqQuery. Схема публикуется, но на запрос приходит ошибка:
The server encountered an error processing the request. The exception message is 'Элемент коллекции с именем StatusId не найден'.
Если убрать эту строку из кода - ругается на следующую ContactId, хотя обе эти колонки есть в таблице Application
public string UsrGetAppInfoByContactINN(string INN) { // Результат по умолчанию. var result = ""; // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных. var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application"); // Добавление колонок в запрос. esqQuery.AddColumn("INN"); esqQuery.AddColumn("[AppStatus:Id:StatusId].Name"); esqQuery.AddColumn("[Contact:Id:ContactId].INN"); // Фильтрация данных запроса. var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN); esqQuery.Filters.Add(esqFilter); // Получение результата запроса. string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); // Возвратить результат. return result;
Что я делаю не так?
Нужно писать названия полей без Id, см. примеры по ссылке выше.
Зверев Александр,
не понимаю почему без Id, если колонки в таблице так и называются: ContactId, StatusId, но это помогло, спасибо.
Правда теперь после отправки запроса - я получаю пустой ответ на запрос:
{"UsrGetAppInfoByContactINN":""}
Александр О,
здравствуйте! Далее Вам необходимо получить коллекцию
var collection = esqQuery.GetEntityCollection(UserConnection); if(collection.Count > 0) { foreach(var entity in collection) { var name = entity.GetTypedColumnValue<string>("Name"); } }
Примерно так.
Только еще один момент, Вам необходимо получить названия колонок в esqQuery, что бы потом можно было выбирать из коллекции по имени.
var appColName = esqQuery.AddColumn("[AppStatus:Id:StatusId].Name").Name; var collection = esqQuery.GetEntityCollection(UserConnection); if(collection.Count > 0) { foreach(var entity in collection) { var name = entity.GetTypedColumnValue<string>(appColName); } }
Александр О пишет:
не понимаю почему без Id, если колонки в таблице так и называются
Оно в этом случае не пишется, при генерации запроса подставляется автоматически.
Нигрескул Алексей,
с помощью Ваших рекомендаций и дополнительных танцев с бубном схема видоизменилась на:
public string UsrGetAppInfoByContactSSN(string ContactINN) { var result = ""; var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application"); var appColApplicationId = esqQuery.AddColumn("Id").Name; var appColStatus = esqQuery.AddColumn("Status.Name").Name; var appColINN = esqQuery.AddColumn("Contact.INN").Name; var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN); esqQuery.Filters.Add(esqFilter); var collection = esqQuery.GetEntityCollection(UserConnection); if(collection.Count > 0) { foreach(var entity in collection) { var name = ("ApplicationId:").ToString() + entity.GetTypedColumnValue<string>(appColApplicationId) +(", Status:").ToString() + entity.GetTypedColumnValue<string>(appColStatus) +(", INN:").ToString() + entity.GetTypedColumnValue<string>(appColINN); return name; } } return result;
В результате в ответ на запрос получаю:
{"UsrGetAppInfoByContactSSNResult":"ApplicationId:cee41684-295b-4384-8dfb-1fa3fdd835cc, Status:Підтверджена, INN:4562378478"}
Но это только одна запись.
Что нужно изменить в схеме чтобы в ответе приходили все найденные записи? Например так:
{"UsrGetAppInfoByContactSSNResult": "ApplicationId:a913e1c5-6e83-428c-b095-0cf1b3aca5bf, Status:Підтверджена, INN:4562378478" "ApplicationId:cee41684-295b-438e-8dfb-1fa3fdd835cc, Status:В роботі, INN:4562378478" "ApplicationId:47a7a0be-4c21-430f-9da9-7d1b658cff92, Status:Відмовлено, INN:4562378478" }
Александр О,
здравствуйте! В таком случае я бы сделал так:
public class AppInfoByContactSSN { public Guid ApplicationId {get;set;} public string StatusName {get;set;} public string Inn {get; set;} } public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) { var result = new List<AppInfoByContactSSN>(); var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application"); var appColApplicationId = esqQuery.AddColumn("Id").Name; var appColStatus = esqQuery.AddColumn("Status.Name").Name; var appColINN = esqQuery.AddColumn("Contact.INN").Name; var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN); esqQuery.Filters.Add(esqFilter); var collection = esqQuery.GetEntityCollection(UserConnection); if(collection.Count > 0) { foreach(var entity in collection) { result.Add(new AppInfoByContactSSN { ApplicationId = entity.GetTypedColumnValue<Guid>(appColApplicationId), StatusName = entity.GetTypedColumnValue<string>(appColStatus), Inn = entity.GetTypedColumnValue<string>(appColINN) }); } } return result; }
Нигрескул Алексей,
пришлось еще добавить в using System.Collections.Generic;
Но при публикации на строку:
public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) {
выдает ошибку: a namespace cannot directly contain members such us fields or methods.
Полный код:
namespace Terrasoft.Configuration.UsrCustomNamespace { using System; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using Terrasoft.Core; using Terrasoft.Web.Common; using Terrasoft.Core.Entities; using System.Collections.Generic; [ServiceContract] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] public class AppInfoByContactSSN { public Guid ApplicationId {get;set;} public string StatusName {get;set;} public string Inn {get; set;} } [OperationContract] [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)] public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) { var result = new List<AppInfoByContactSSN>(); var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application"); var appColApplicationId = esqQuery.AddColumn("Id").Name; var appColStatus = esqQuery.AddColumn("Status.Name").Name; var appColINN = esqQuery.AddColumn("Contact.INN").Name; var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN); esqQuery.Filters.Add(esqFilter); var collection = esqQuery.GetEntityCollection(UserConnection); if(collection.Count > 0) { foreach(var entity in collection) { result.Add(new AppInfoByContactSSN { ApplicationId = entity.GetTypedColumnValue<Guid>(appColApplicationId), StatusName = entity.GetTypedColumnValue<string>(appColStatus), Inn = entity.GetTypedColumnValue<string>(appColINN) }); } } return result; } }
Так у Вас метод не внутри класса, а после, потому и ругается. Метод должен быть в классе, а не в окружающем его namespace.
Зверев Александр,
так тоже пробовал, но на строку:
var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
выдает ошибку:
An object reference is required for t he non-static field, method, or property 'User.Connection.EntitySchemaManager'
и на строку:
var collection = esqQuery.GetEntityCollection(UserConnection);
выдает ошибку:
'UserConnection' is a type, which is not valid in the given context
Александр, значит, у Вас в переменной UserConnection не то, что должно там быть. Попробуйте поискать в конфигурации или на этом сайте примеры, как правильно делать. А если выдаёт ошибку, то по её тексту можно найти поиском в Интернете более подробное пояснение, что это означает.
Пример создания сервиса есть тут. Как минимум, у Вас не хватает наследования класса от BaseService.