Я добавил SqlExpressionSelectFilter
для использования функциональности soft delete в ServiceStack OrmLite. Однако кажется, что фильтр применяется только к базовой таблице, указанной в From<T>
, а не к любым таблицам, объединенным с Join<TFrom, TOther>
. Оба моих типа реализуют интерфейс, который я использую в своем фильтре. Это то, что поддерживается?
Фильтр:
OrmLiteConfig.SqlExpressionSelectFilter = query =>
{
if (query.ModelDef.ModelType.HasInterface(typeof(IHasRecordStatus)))
{
query.Where<IHasRecordStatus>(q => q.RecordStatus != RecordStatus.Deleted);
}
};
Интерфейс:
public interface IHasRecordStatus
{
[Alias("RECORD_STATUS")]
RecordStatus RecordStatus { get; set; }
}
[EnumAsInt]
public enum RecordStatus : byte
{
Added = 1,
Changed = 2,
Deleted = 3
}
POCO которые:
[Alias("ITEM_MASTER")]
public class ItemMaster : IHasRecordStatus
{
[PrimaryKey]
[Alias("ITEM_ID")]
public int Id { get; set; }
[Alias("UPC_EAN")]
public string Upc { get; set; }
[Alias("RECORD_STATUS")]
public RecordStatus RecordStatus { get; set; }
}
[Alias("VENDOR_ITEM")]
public class VendorItem : IHasRecordStatus
{
[Alias("VI_ID")]
public int Id { get; set; }
[Alias("ITEM_ID")]
public int ItemId { get; set; }
[Alias("V_ID")]
public int VendorId { get; set; }
[Alias("RECORD_STATUS")]
public RecordStatus RecordStatus { get; set; }
}
Запрос:
var query = db.From<VendorItem>()
.Join<VendorItem, ItemMaster>((vi, im) => vi.ItemId == im.Id)
.Take(2);
var result = db.Select(query);
Выходной SQL:
SELECT TOP 2 "VENDOR_ITEM"."VI_ID" AS "Id", "VENDOR_ITEM"."ITEM_ID" AS "ItemId", "VENDOR_ITEM"."V_ID" AS "VendorId", "VENDOR_ITEM"."RECORD_STATUS" AS "RecordStatus"
FROM "VENDOR_ITEM" INNER JOIN "ITEM_MASTER" ON ("VENDOR_ITEM"."ITEM_ID" = "ITEM_MASTER"."ITEM_ID")
WHERE ("VENDOR_ITEM"."RECORD_STATUS" <> @0)
В генерируемом SQL я ожидал бы, что предложение where также будет содержать (AND "ITEM_MASTER"."RECORD_STATUS" <> @1)
, но оно содержит только фильтр для таблицы VendorItem, указанной в предложении from.
Мне также показалось странным, что мне пришлось указывать псевдоним как на интерфейсе, так и на классах, которые его реализуют, чтобы он работал. Я пробовал это только на интерфейсе и только на POCO, и ни один не работал, пока я не указал оба. Это по замыслу?