Re[9]: Несколько вопросов по Меппарам.
От: IT Россия linq2db.com
Дата: 20.05.05 03:02
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

IT>>Бизнес логике в БД вообще нечего делать. По многим причинам.

ГВ>Угу. Есть только одна веская причина, по которой БЛ имеет смысл перетащить в БД: производительность на больших массивах. Но она находится в жёстком противоречии с гибкостью.

Абсолютно верно. Но в этом случае мы точно знаем за что платим.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Несколько вопросов по Меппарам.
От: GlebZ Россия  
Дата: 20.05.05 15:42
Оценка: 3 (1)
Здравствуйте, igor_fle, Вы писали:

Наконец руки дошли.
Что-то мне это не сильно нравится все это. Кому-то надо, кому-то не надо. Если нельзя объединять усилия по достижению общей цели, то менеджеров к стенке надо ставить. (или в сортире мочить как учит одно небезызвестное лицо) . Унифицировать интерфейсы(и состояние бизнес объектов) архиважная задача на пути к коммунизму и снижения издержек при буржуазном строе. Решить это политически значительно дешевле чем реализацию(с постановкой и тестированием). Это по количеству данных(состоянию) в возвращаемом объекте. Что касается самих объектов, то тот кому нужны адреса, должен заказывать адреса. Тому кому нужно companies тот заказывает companies. Это нормально.

Теперь по решению.
Самое простое решение описанное во все книжках. Каждый заказывает то что ему нужно. То бишь:
interface MyInterface{
GetCompany(id);
GetAdress(companyId);
GetCompanyFinancialDetails(id);
}

Каждый берет столько сколько нужно. Правда маленький недостаток. Оверхед количества вызовов. Проверено на практике, что кроме криминальных случаев, некоторый оверхед по объему дешевле чем оверхед по количеству вызовов. Поэтому дополнительно предлагаю следующий вариант.
Клиент:
Finder finderCompany=new Finder();
finderCompany.ObjectName="Company";//имя заказываемого объекта
finder.AddEqualPredicate("id", 1000);//получить те объекты у которого поле id=1000
Finder finderAddress=new Finder();
finderAddress.ObjectName="Address";
finderCompany.AddJoin(finderAddress, "AddressId", "Id");//добавляем связку показывающую что также нужны адреса.
server.GetCompanies(finder);

На сервере. Тут нужно всегда знать что если работаешь c layer'ами, изволь ими пользоваться. Поэтому тут задача передать заказ из внешнего слоя в нижний решается с помощью сервиса(если конечно это не Domain Model), допустим это объект ObjectGetter.
public DTO MyInterface.GetObjects(Finder finder)
{
  IList companies=ObjectGetter.GetByFinders(finder);
    return FormatDTO.FormatDTOFromObjects(companies);//форматируем в формат протокола пересылки бизнес объектов
}
//здесь у нас описывается запрос уже в терминах SQL.
public struct SelectDescription
{
    string _selectFields;//строка для селектов
    string _from;//строка для from (но без joins)
    string _predicates; // строка для where
    Join[] _joins;//описываем с кем связаны
    string _alias;//алиас таблицы в запросе для данного маппера
    IMapper _mapper; //ссылка на того, кто будет собирать результаты из него
}
//отдельно описываем джоины
public struct Join
{
  string _predicate;//предикат связываения
    EnumTypeJoin _typeJoin;//по какому joinу (внешний, внутренний)
    SelectDescription _joinedDescription;//кого приджоиним
}

//само получение данных
public IList ObjectGetter.GetByFinder(Finder finder)
{
  SelectDescription selectDescriptor=GenerateDescriptor(finder);
    //из полученных данных генерируем запрос
    string sqlSelect=GenerateCommandString(selectDescription);
    ArrayList result=new ArrayList();
    //естественно, если нужна независимость от базы данных, или транзакции то операции БД в отдельные классы
    using (SqlConnection connection=new SqlConnection(connectionString))
    {
        myConnection.Open();
        using(SqlDataReader myReader = new SqlCommand(sqlSelect, myConnection).ExecuteReader(CommandBehavior.CloseConnection))
        {
            while(myReader.Read()) 
            {
                ReadFromReader(result, myReader, selectDescription);
            }
            myReader.Close();
        }
    }
    return result;
}


//заполняем структуру SelectDescription уже SQL данными 
public SelectDescription ObjectGetter.GenerateDesciptor()
{
    //обязательно пытаемся делать через маппер для конретного типа.
    //Тогда мы можем управлять поведением заполнения и языка запросов
    //в случае наличия универсального хранилища метаданных(и следовательно управления языком запросов)
    // это можно сделать через один объект
    IMapper mapper=GetMapperByObjectName(finder.ObjectName);
    //создаем дескриптор для построение select 
    //второй параметр важен. алиас должен быть уникальным.
    SelectDescription descriptor=mapper.GetSelectDescription(mapper, GenerateAlias());
    //рекурсивно делаем joins
    foreach(Finder finderJoined in finder.Joins)
    {
        SelectDescription joinedDescriptor=ObjectGetter.GenerateDescriptor(finder, GenerateAlias());
        AppendJoin(desciption, joinedDescription);//заполняем структуры Join
    }
    return descriptor;
}
//чтение объекта из строки
public void ReadFromReader(ArrayList arrayResult, SqlDataReader myReader, SelectDescription descriptor)
{
    //создают и заполняют объекты безусловно мапперы
  descriptor.Mapper.LoadObjects(arrayResult, description, myReader);
    //заполняем по рекурсии joins
    foreach (Join join in descriptor.Joins)
        ReadFromReader(arrayResult, myReader, join.SelectDescriptor);
    return arrayResult;
}

Код написан только примерно и сходу. Поэтому там должно быть множество ошибок (я так думаю). Просто описано достаточно, чтобы понять само решение. Result может быть (а обычно бывает) не просто ArrayList, а более сложным.

С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[21]: Несколько вопросов по Меппарам.
От: sfsoft Россия  
Дата: 01.01.06 14:58
Оценка:
Жалко, что тема загнулась...
Re[9]: Несколько вопросов по Меппарам.
От: Damat Украина  
Дата: 03.01.06 08:08
Оценка:
Привет.

Очень интересно, что такая длинная полемика по одному вопросу
Не смог удержаться от комментария.

Собственно, мой подход в принципе — это упрощенная модель БО — без
знания про источник данных(БД)

Например ситуация: при SOA(service oriented architecture) уже никак
нельзя хранить в БО объекты доступа к источнику даных, тк сборка со всеми
БО должна быть отдельной для использования на:
— серверной стороне наряду с функциональностью доступа к БД;
— и на клиенте(отображение), чтобы не плодить лишних сущностей.

Еще замечание про ПРОКСИ. Всем известно, что проксииспользуется для:
— lazy loading,
— code security,
— remote communication.
Но, его использование — требует кодирования, при чем однотипного
Сразу оговорюсь, я давно уже это не пису, ибо EMIT как раз мне и помогает,
конечно не сырой, а в прикольной реализации пришлось...
Собственно, всякие такие штуки должны использоваться в контексте системы
генерации кода, если даная ситуация происходит часто и решается через
копирование и подправление. А кто потом менять в 100 местах будет, уж если
поменять захочется.

Еще, есть отличные ОРМ помощнички, которые неплохо работают. В том, что
я использую ВСЕГДА есть 2 режима генерации
— SelfServicing — объект сам отвечает за вычитку себя из базы (активный можно так сказать)
— Adapter — работа через адаптер (пасивный)

И напоследок, для меня самым важным моментом проектирования является разбиение на модули и
ПРАВИЛЬНАЯ их ссылочнотсь друг на друга — такой себе граф (конечно без зацикливаний).
Рисунок очень наглядноотражает основные подходы: low coupling & high cohesion, а сдесь и
переносимость, и и универсальность, и еще куча всего приятного


Будущее за BizTalk!!!
Re[10]: Несколько вопросов по Меппарам.
От: IDL  
Дата: 09.01.06 17:42
Оценка:
Здравствуйте, Damat, Вы писали:

D>И напоследок, для меня самым важным моментом проектирования является разбиение на модули и

D>ПРАВИЛЬНАЯ их ссылочнотсь друг на друга — такой себе граф (конечно без зацикливаний).
D>Рисунок очень наглядноотражает основные подходы: low coupling & high cohesion, а сдесь и
D>переносимость, и и универсальность, и еще куча всего приятного
А каким ORM средством ты пользуешся
Re[11]: Несколько вопросов по Меппарам.
От: Damat_AE Украина  
Дата: 11.01.06 07:28
Оценка:
Здравствуйте, IDL, Вы писали:

IDL>Здравствуйте, Damat, Вы писали:


D>>И напоследок, для меня самым важным моментом проектирования является разбиение на модули и

D>>ПРАВИЛЬНАЯ их ссылочнотсь друг на друга — такой себе граф (конечно без зацикливаний).
D>>Рисунок очень наглядноотражает основные подходы: low coupling & high cohesion, а сдесь и
D>>переносимость, и и универсальность, и еще куча всего приятного
IDL>А каким ORM средством ты пользуешся


LLBLGEN PRO
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.