Всем привет!
Попробовал использовать BLT с PostgreSQL через сгенеренные T4 классы.
Основных проблем на данный момент две:
1)При использовании схем объектов (обращение к объекту "schemaName"."TableName") PostgreSQL.ttinclude неправильно определяет схему. Вместо имени схемы он вставляет owner'а. По этому случаю нужно сделать патч на PostgreSQL.ttinclude
http://emanovs.narod.ru/PostgreSQL.ttinclude
К сожалению приложить файл не получилось, так как при загрузке файла выдается Access denied (пользуюсь FF4).
Кстати, непонятно,почему используется связка OwnerName.TableName? Ноги растут из SQL2000?
2) Для PostgreSQL важно, чтобы в случае имен с разным регистром использовались кавычки, в патче для этого есть решение. Получаются классы вида
[TableName(Owner = "\"main\"", Name = "\"Track\"")]
public partial class Track
{
[MapField("\"Id\""), Identity, PrimaryKey(1), Required] public Int64 Id { get; set; } // bigint
[MapField("\"Uid\""), Required] public Guid Uid { get; set; } // uuid
[MapField("\"MemberId\""), Required] public Int64 MemberId { get; set; } // bigint
}
Но появляется проблема, которую я пока не знаю как решить: Возвращаемые данные при таком подходе с колонками:
Id, Uid, MemberId
не могут замапиться на колонки
"Id", "Uid", "MemberId"
Как красивей обойти проблему?
Проблема с кавычками видна на примере запроса:
var tracks = tt.Track.Where(x => x.Uid == input.track_uid);
long trackId;
if (tracks.Count() != 0){};
без патча (в части имён объектов) это приводит к ошибке из-за поля x.Uid:
SELECT
Count(*) as cnt
FROM
"main"."Track" x
WHERE
x.Uid = ((E'516bf297-6cf8-4119-87c8-91579f8dca41'))
с патчем даёт запрос почти корректный на вид:
SELECT
x."Id" as Id,
x."Uid" as Uid1,
x."MemberId" as MemberId
FROM
"main"."Track" x
WHERE
x."Uid" = :track_uid
Кстати, непонятно почему для Uid поля используется alias Uid1. Это будет мешать маппингу, ведь на выходе ожидается поле Uid.
Пока первое что приходит в голову — каким-то образом разрешить маппинг для Entity и запретить для передачи параметров/получения результатов. Даже не знаю, насколько это возможно.
И да, по крайней мере, команду получения метаданных в PostgreSQL.ttinclude нужно поменять:
cmd.CommandText = @"
SELECT
pg_class.oid,
pg_namespace.nspname,
pg_class.relname,
pg_class.relkind
FROM
pg_class
INNER JOIN pg_user ON (pg_class.relowner = pg_user.usesysid)
INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
WHERE
pg_class.relkind IN ('r','v')
AND pg_namespace.nspname NOT IN ('pg_catalog','information_schema')";
это та часть, которая отвечает за использование имени схемы в качестве owner'а.
В общем, как я понимаю, самое простое решение — генерировать код SQL в базовых классах, заключая имена полей и объектов в кавычки. На MSSQL вредного влияния это не окажет.
Окончательно разобрался с проблемой.
Итак, нужно поправить PostgreSQL.ttinclude, чтобы использовались правильные схемы:
http://emanovs.narod.ru/PostgreSQL.ttinclude
И нужно поправить PostgreSQLDataProvider.cs для возможности конфигурирования квотирования идентификаторов:
http://emanovs.narod.ru/PostgreSQLDataProvider.cs
само конфигурирование как обычно:
<bltoolkit>
<dataProviders>
<add type="BLToolkit.Data.DataProvider.PostgreSQLDataProvider,BLToolkit.Data.DataProvider.PostgreSQL.4" QuoteIdentifiers="true"/>
</dataProviders>
</bltoolkit>
Кроме того в проект BLToolkit.Data.DataProvider.PostgreSQL.4.csproj
необходимо добавить сборку System.Data.Linq
чтобы он собирался