Получение значений связанных объектов в конфигурационном веб-сервисе
Доброго времени суток! Коллеги, помогите пожалуйста с переводом запроса 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.