Dapper - region/lokalizacja

0

W nawiązaniu do wątku
Najszybszy sposób na pobranie dużej ilości danych - API + MS SQL
Postanowiłem przetestować Dapper i niestety... Chyba miałem za duże oczekiwania.
Poradziłem sobie z zagnieżdzonymi obiektami, działa to super i szybko, ale problem zaczyna się z głupotami regionalnymi... Nie cierpie tego kraju patrząc oczami programisty.

  1. Dapper nie mapuje mi bazodanowych decimali, ponieważ w bazie jest kropka zamiast przecinka
  2. Mam w tabeli 3 kolumny datetime - dwie z nich mapuje poprawnie, trzecią pokazuje jako 01.01.0001 00:00:00

Domyślam się, że to jest kwestia regionu i CultureInfo wątku, ale nawet

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");

Nie pomaga, ponieważ decimale w obiektach dalej pokazują 0 i dwie pierwsze daty mapuje poprawnie, tylko w formacie amerykańskim (10/09/2018 1200 AM). Zmiana regionu w bazie danych nie wchodzi w grę, nie moja baza.
Ktoś ma na to rozwiązanie, aby uruchamiając aplikacje gdziekolwiek, dane były wczytywane poprawnie bezwzględu na region czy lokalizację?

0

Możesz podać definicję tabeli (SQL) i kod z użyciem Dappera do zreprodukowania tego problemu?

0

W załączniku wrzucam backup bazy demo z przykładowym dokumentem. Tabela nazywa się TraNag.
Kolumny TrN_DataDok, TrN_DataOpe mappują się poprawnie. Zaś TrN_Termin pokazuje 01.01.0001 00:00:00.
Kolumny TrN_RazemNetto, TrN_RazemVAT oraz TrN_RazemBrutto są kolumnami decimal i tutaj mam wszędzie 0.

    public class TraNag
    {
        public int TrN_TrNID { get; set; }
        public int TrN_DDfId { get; set; }
        public string TrN_NumerPelny { get; set; }
        public string TrN_TypDokumentu { get; set; }
        public Kontrahent Nabywca { get; set; }
        public Kontrahent Odbiorca { get; set; }
        public Kontrahent Platnik { get; set; }
        public int TrN_PodID { get; set; }
        public int TrN_OdbID { get; set; }
        public short TrN_Bufor { get; set; }
        public DateTime TrN_DataDok { get; set; }
        public DateTime TrN_DataOpe { get; set; }
        public int TrN_FpLID { get; set; }
        public string TrN_Termin { get; set; }
        public decimal TrN_RazemNetto { get; set; }
        public decimal TrN_RazemVAT { get; set; }
        public decimal TrN_RazemBrutto { get; set; }
        public string TrN_Waluta { get; set; }
    }
    public static List<TraNag> GetAllDocuments(string docType, DateTime from, DateTime to, string customer)
    {
        string query = $@"select * from CDN.TraNag
                        left join CDN.Kontrahenci on TrN_PodID = Knt_KntId
                        where TrN_TypDokumentu = {docType} and convert(date, TrN_DataDok) >= convert(date, '{from.ToString("yyyy-MM-dd")}')
                        and convert(date, TrN_DataDok) <= convert(date, '{from.ToString("yyyy-MM-dd")}')";

        using (IDbConnection db = new SqlConnection(ConnectionString 
        {
            if (db.State == ConnectionState.Closed) 
                db.Open();

            return db.Query<TraNag, Kontrahent, TraNag>(query, (trn, knt) =>
            {
                trn.Nabywca = knt;
                trn.Odbiorca = knt;
                return trn;
            },
            splitOn: "TrN_PodID").ToList();
       }
  }
1

Słyszałeś kiedyś może o tym że parametryzowanie zapytań zarówno zabezpiecza przed sqlinjection jak i przyśpiesza ich wykonanie przez DB?

Jak nie to najwyższa pora się tym zainteresować, bo sklejanie sql czy też ich interpolowanie to nie jest dobry pomysł :).

0

Zrzuciłem całą bazę do pliku SQL. Jak coś to się dostosuje, chciałbym z projektem pójść do przodu w końcu.

#edit
@neves
Tak wiem. To jest tylko test i tymczasowe, żeby załapać o co kaman z dapperem i sprawdzić czy dobre rozwiązanie do mojego projektu.

0

Chyba mam, ale nie jestem pewien co robie źle. Jeśli wywale kompletnie join z zapytania i będę się starał wyciągnąć tylko TraNag to mappuje wszystkie daty i decimale też:

        public static List<TraNag> GetAllTraNags(string docType, DateTime from, DateTime to, string customer)
        {
            string query = $@"select tn.* from CDN.TraNag tn
             where tn.TrN_TypDokumentu = {docType} and convert(date, tn.TrN_DataDok) >= convert(date, '{from.ToString("yyyy-MM-dd")}') 
             and convert(date, tn.TrN_DataDok) <= convert(date, '{to.ToString("yyyy-MM-dd")}')";

            using (IDbConnection db = new SqlConnection(ConnectionString))
            {
                if (db.State == ConnectionState.Closed)
                    db.Open();

                return db.Query<TraNag>(query).ToList();
            }
        }

Czy ten splitOn: "TrN_PodID" jest źle? Czy to dlatego, że TrN_PodID = Knt_KntId nie są kolumnami o tej samej nazwie? W dokumentacji Dappera jest przykład z InvoiceID i obie joinowane kolumny mają taką samą nazwę. Problem w przypadku joina leży tylko po stronie nieprawidłowego mappowania TraNag, Kontrahent jest dobrze, czyli poniekąd join działa, ale psuje TraNag... WTF?

Przykład z dokumentacji Dapper - Query Multi-Mapping (One to One)

string sql = "SELECT * FROM Invoice AS A INNER JOIN InvoiceDetail AS B ON A.InvoiceID = B.InvoiceID;";

using (var connection = My.ConnectionFactory())
{
    connection.Open();

    var invoices = connection.Query<Invoice, InvoiceDetail, Invoice>(
            sql,
            (invoice, invoiceDetail) =>
            {
                invoice.InvoiceDetail = invoiceDetail;
                return invoice;
            },
            splitOn: "InvoiceID")
        .Distinct()
        .ToList();
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1