StackService динамическое DTO

1

Я пытаюсь создать динамический DTO для использования в ServiceStack. Причина в том, что данные запрашиваются из базы данных, не зная количества возвращенных столбцов и, следовательно, не могут создать нормальное dto.

ОБНОВЛЕНИЕ: причина не знать количество столбцов заключается в том, что для возврата данных используется стержень. Достаточно просто:

CustID | OrderDate | Qty
1      | 1/1/2008  | 100
2      | 1/2/2008  | 200
1      | 2/2/2008  | 350
2      | 2/28/2008 | 221
1      | 3/12/2008 | 250
2      | 3/15/2008 | 2150

в это.

CustID  | Jan- 2008 | Feb- 2008 | Mar - 2008 |
1       | 100       | 350       |  250
2       | 200       | 221       | 2150

пользователь сможет указать дату начала и окончания и, следовательно, определить количество столбцов в результате.

ОБНОВЛЕНИЕ КОНЕЦ

Мой код:

DTO

public class Rep_DataAvailibility
{
    public DateTime startDate { get; set; }
    public DateTime endDate { get; set; }
}

public static class Rep_DataAvailibilityData
{
    private static string _commandText = "select name,description,Constant from measurement"; // used as a test

    public static object GetData(Rep_DataAvailibility parameters)
    {
        object result = new object();
        using (IDbConnection db = DataHelper.DbProvider.OpenDbConnection())
        {
            result = db.Query<object>(_commandText).ToArray();           
        }
        return result;
    }
} 

API

public partial class Rep_DataAvailibilityService : Service
{
    //[Authenticate]
    public object Get(Rep_DataAvailibility request)
    {
        return Rep_DataAvailibilityData.GetData(request);
    } //end of GET endpoint
}//end of service class

Если пять элементов, куда нужно вернуть, это результат: [{}, {}, {}, {}, {}]

Я тоже пробовал использовать словарь, но это тоже не сработало, кажется, я, возможно, неправильно понял это и поэтому не буду подробно излагать, поскольку мне нужно еще кое-что прочитать.

Любая помощь приветствуется.

Спасибо, Иоганн

Теги:
ormlite-servicestack
servicestack

1 ответ

2
Лучший ответ

Сопоставьте класс POCO 1:1 с таблицей РСУБД

То, что вы пытаетесь достичь, противоречит целям ORM, таким как OrmLite, который предназначен для работы с известными типами и POCOs. Из официальной документации основная цель OrmLite заключается в следующем:

Сопоставьте класс POCO 1:1 с таблицей РСУБД, чисто по соглашениям, без каких-либо атрибутов.

Использование object

Если вы предоставляете простой object качестве своего типа, то есть db.Query<object>, тогда нет никаких публичных свойств этого объекта, чтобы отражать возвращаемые данные запроса, поэтому вы получаете [{},{},{},{},{}].

NoSQL?

Это не похоже на хорошую совместимость с ORM и, возможно, даже с реляционной базой данных. Необычно запрашивать таблицу RDBMS и не знать столбцы, которые она вернет. Это похоже на территорию NoSQL, где вам нужна структура данных.


Поверните данные в своей бизнес-логике:

Ваша проблема в конечном счете заключается в создании стержня ваших данных в базе данных, потому что это создает динамические столбцы. Проблема может быть легко решена, если вы вернули список заказов и выполнили опорный пункт в своем коде.

Поэтому, если вы создали объект для представления таблицы заказов:

public class Order
{
    public int CustID { get; set; }
    public DateTime OrderDate { get; set; }
    public int Qty { get; set; }
}

Затем вы можете запросить базу данных для List<Order> а затем повернуть эти данные в подходящий DTO, например:

public class CustomerMonthlyOrders
{
    public int CustID { get; set; }
    public Dictionary<string, int> QuantitiesOrdered { get; set; }
}

Поэтому, учитывая маршрут:

[Route("/orders", "GET")]
public class GetOrderHistoryRequest : IReturn<List<CustomerMonthlyOrders>>
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

Ваша служба может сворачивать данные: Примечание: SQL не проверен и нуждается в настройке в вашу базу данных.

public class OrderService : Service 
{
    public List<CustomerMonthlyOrders> Get(GetOrderHistoryRequest request)
    {
        // Perform the query to get all orders within the range
        // (NOTE: SQL is untested, and will need tweaked to your db)
        List<Order> allOrders = Db.SqlList<Order>("SELECT * FROM Orders WHERE OrderDate >= @Start AND OrderDate < @End", new {
            Start = request.StartDate,
            End = request.EndDate
        });

        // Prepare response object
        var customerMonthlyOrders = new List<CustomerMonthlyOrders>();

        // Get the distinct customer Ids
        var customers = orders.Select(o => o.CustID).OrderBy(o => o).Distinct();
        foreach(var custId in customers)
        {
            // Create a result for the customer
            var result = new CustomerMonthlyOrders { 
                CustID = custId,
                QuantitiesOrdered = new Dictionary<string, int>()
            };

            // Get the customers relevant orders
            var orders = allOrders.Where(o => o.CustID == custId);
            foreach(var order in orders)
            {
                // Determine the month the order belongs to (i.e. the key)
                var month = order.OrderDate.ToString("MMM-yyyy");

                // Add or update the quantities
                if(result.QuantitiesOrdered.ContainsKey(month))
                    result.QuantitiesOrdered[month] += order.Qty;
                else
                    result.QuantitiesOrdered.Add(month, order.Qty);
            }

            // Add the customers order to the results
            customerMonthlyOrders.Add(result);
        }

        // Return the results
        return customerMonthlyOrders;
    }
}

Затем создается динамический ответ DTO, который вы ищете:

Изображение 174551

JSON выпустил:

[{
    "CustID": 1,
    "QuantitiesOrdered": {
        "Jan-2008": 100,
        "Feb-2008": 350,
        "Mar-2008": 250
    }
}, {
    "CustID": 2,
    "QuantitiesOrdered": {
        "Jan-2008": 200,
        "Feb-2008": 221,
        "Mar-2008": 2150
    }
}]
  • 0
    спасибо за решение. Если сводное действие перемещается в бизнес-логику, динамические столбцы больше не возвращаются из базы данных, следовательно, нет необходимости в динамическом DTO.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню