powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Самописный адаптер для контрактов WCF
6 сообщений из 6, страница 1 из 1
Самописный адаптер для контрактов WCF
    #38005479
НовыйЯ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, есть wcf, который содержит интерфейсы для дёргания кучи процедур отчётов их базы.
Процедур дофигища, каждая возвращают набор данных в виде единственной таблицы с фиговой тучей полей.

Если возвращать DataTable, то написание и поддержка этого дела сведётся к очень простому коду вида
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
        //заполняется вектор входных параметров
        SqlParamCollection Params = new SqlParamCollection();
        Params.AddParam("@DateTo", typeof(DateTime), DateTo);
        Params.AddParam("@region_id", typeof(int), region_id);
        Params.AddParam("@owner_id", typeof(string), owner_id);
        Params.AddParam("@house_id", typeof(string), house_id);
        Params.AddParam("@date_rsbu", typeof(DateTime), date_rsbu);
        Params.AddParam("@DateMSFOFrom", typeof(DateTime), DateMSFOFrom);
        Params.AddParam("@DateMSFOTo", typeof(DateTime), DateMSFOTo);
        Params.AddParam("@multiOIDP", typeof(string), multiOIDP);

       // Вызывается унирерсальный метод, 
       //возвращающий заполненную данными таблицу
       //по имени процедуры и вектору входных параметров
       private DataTable FillDataTable(String _procName, object _params)
    {
        DataTable DT = new DataTable();
        DT.TableName = _procName;

        SqlParamCollection Params = _params as SqlParamCollection;
        String ProcName = _procName;

        DA = new SqlDataAdapter(ProcName, DBase.Conn);

        try
        {
            if (DBase.Conn.State == ConnectionState.Closed) DBase.Conn.Open();

            DA.SelectCommand.CommandType = CommandType.StoredProcedure;
            DA.SelectCommand.CommandTimeout = 0;

            foreach (SqlParam p in Params)
            {
                if (p.ParValue == null)
                    DA.SelectCommand.Parameters.AddWithValue(p.ParName, System.DBNull.Value);
                else
                {
                    DA.SelectCommand.Parameters.Add(p.ParName, p.ParSqlType);
                    DA.SelectCommand.Parameters[p.ParName].Value = Convert.ChangeType(p.ParValue, p.ParType);
                }
            }

            DA.Fill(DT);

        }
        catch (Exception exc)
        {
            throw new Exception("Не удалось загрузить данные из базы!\n\r " + exc.ToString());
        }
        finally
        {
            DBase.Conn.Close();
        }



Но вот если писать контракты, тогда придётся описывать все поля возвращаемых данных и писать многокилометровые простыни из самих контрактов и ридеров для них.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
 [DataContract]
    public sealed class ContrRpt24 
    {
        [DataMember]
        public string new_region;

        [DataMember]
        public string f_new_name;

        [DataMember]
        public string fw_new_name;
        
        //... много-много таких полей, за описанием которых надло лезть в процедуру с кучей джойнов, 
       //искать таблицы, в таблицах - поля и их типы (в то время как SqlDataAdapter умеет это делать сам!!!)
    }


     public ContrRpt24[] GetContrRpt24Params(DateTime? DateTo, int region_id, string owner_id, string house_id, DateTime? date_rsbu, DateTime? DateMSFOFrom, DateTime? DateMSFOTo, string multiOIDP)
        {

            List<ContrRpt24> records = new List<ContrRpt24>();

            string sp = "Report_24";

            
            using (SqlCommand cmd = new SqlCommand(sp, DBase.Conn))
            {
                SqlDataReader reader;
                try
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandTimeout = 0;
                    DBase.Conn.Open();

                    SqlParamCollection Params = Params24(DateTo, region_id, owner_id, house_id, date_rsbu, DateMSFOFrom, DateMSFOTo, multiOIDP);

                    foreach (SqlParam p in Params)
                    {
                        if (p.ParValue == null)
                            cmd.Parameters.AddWithValue(p.ParName, System.DBNull.Value);
                        else
                        {
                            cmd.Parameters.Add(p.ParName, p.ParSqlType);
                            cmd.Parameters[p.ParName].Value = Convert.ChangeType(p.ParValue, p.ParType);
                        }
                    }

                    reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                    while (reader.Read())
                    {
                        ContrRpt24 r = new ContrRpt24();
                        r.new_region = reader["Географическое положение"].ToString();
                        r.f_new_name = reader["Наименование ОН"].ToString();
                        r.fw_new_name = reader["Наименование ОН в работе"].ToString();
                        //... и ещё много-много выводимых полей, которые SqlDataAdapter умеет определать сам, за кадром
                        records.Add(r);
                    }
                    if (!reader.IsClosed)
                    {
                        reader.Close();
                    }
                }
                catch (Exception exc)
                {
                    throw new Exception("Не удалось загрузить данные из базы!\n\r " + exc.ToString());
                }
                finally
                {
                    DBase.Conn.Close();
                }
            }//end using  

            return (ContrRpt24[])records.ToArray();
        }



Реально ли написать аналог SqlDataAdapter для контрактов?
Кто-нибудь пробовал?
...
Рейтинг: 0 / 0
Самописный адаптер для контрактов WCF
    #38005803
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НовыйЯ,

тебе хочется написать эммитер(Emit) для класса, чтоль?
в .net можно писать и компилить на лету, правда косяк то в чем. как тебе контракт деплоить.
он же должен быть и там и там, так как не универсален так же как и datatable.

ваще честно тебе сказать, что ты пытаешься решить идеологическую проблему, с помощью вшивой идейки :)
потому что "Процедур дофигища, каждая возвращают набор данных в виде единственной таблицы с фиговой тучей полей." вшивай идейкой не искоренишь.
...
Рейтинг: 0 / 0
Самописный адаптер для контрактов WCF
    #38006063
НовыйЯ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeiKНовыйЯ,

тебе хочется написать эммитер(Emit) для класса, чтоль?
в .net можно писать и компилить на лету,

Плиииииз! Можно об этом поподробнее! Это паттерн какой-то?
Гуглом пока ничего путного про Emit не нашёл. :(

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

Перед тем, как столкнуться с проблемой специфичности DataTable, прочёл о контрактах вот это:
Троелсен Э. - Язык программирования C# 2010 и платформа .NET 4 - 2010Хотя и можно было бы вернуть DataTable из метода службы WCF, вспомним, что технолония WCF обязана следовать принципам SOA, один из которых - программирование на основе контрактов, а не реализаций. Поэтому вместо возврата внешнему клиенту специфичного для .NET типа DataTable, мы вернём специальный контракт данных, который будет корректно выражен в документе WDSL.

Вроде контракт получше в этом отношении, по крайней мере, в конкретном моём случае.

AlexeiKваще честно тебе сказать, что ты пытаешься решить идеологическую проблему, с помощью вшивой идейки :)
потому что "Процедур дофигища, каждая возвращают набор данных в виде единственной таблицы с фиговой тучей полей." вшивай идейкой не искоренишь.
Да я без году неделю программирую на дотнете. у меня вообще идей нет.
Есть только предположение о том, что я далеко не первый, кто с подобным столкнулся, и варианты решения существуют и не единствены. :)
...
Рейтинг: 0 / 0
Самописный адаптер для контрактов WCF
    #38007874
НовыйЯ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
up!
...
Рейтинг: 0 / 0
Самописный адаптер для контрактов WCF
    #38010001
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НовыйЯ,

что ап?
ты токо оправдания написал. вопросов новых нету и не вникнул в "правда косяк то в чем. как тебе контракт деплоить(передавать клиенту)."
...
Рейтинг: 0 / 0
Самописный адаптер для контрактов WCF
    #38010109
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НовыйЯ,

не очень понимаю, что вам надо, но возможно поможет DataContractResolver :
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Самописный адаптер для контрактов WCF
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]