Posted
almost 13 years
ago
by
_Budda_ <[email protected]>
Возникла проблема с конвертацией следующей квери в SQL:
IQueryable<TransferSubscription> subscriptions = db.GetTable<TransferSubscription>();
IList<TransferSubscription> res =
... [More]
subscriptions.Where(subscription => subscription.AmpluaId.HasValue==false || subscription.AmpluaId.Value == amplua)
.ToList()
;
моя табличка содержит поле "amplua_id" типа INT, nullable, мапится так:
[MapField("amplua_id")]
public int? AmpluaId { get; set; }
Говорит
Object reference not set to an instance of an object.
atat BLToolkit.Data.Linq.Builder.TableBuilder.TableContext.ConvertToSql(Expression expression, Int32 level, ConvertFlags flags)
Проблема разрешилась путем замены "AmpluaId.HasValue==false" на "AmpluaId==null".
Это "так и задумано"? или ошибка преобразования "AmpluaId.HasValue" в SQL "aplua_id IS NULL"?
Спасибо. [Less]
|
Posted
about 13 years
ago
by
Terre <[email protected]>
Есть такой запрос:
var query = from _ in serverContext.Trains
select new
{
Id = _.id_train,
DateTime = _.time,
... [More]
Date = _.time.ToShortDateString(),
Time = _.time.ToShortTimeString(),
Scales = _.Scale.name,
Direction = _.Direction.name,
DatabaseName = _.WeightUnit.name,
TrainType = _.TrainType.name,
WagonsCount = _.Wagons.Count(),
WagonsWeight = _.Wagons.Where(w => w.WagonType.type).Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000,
TotalWeight = _.Wagons.Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000
};
который при помощи BLT преобразуется в SQL:
(поля id_train, time1, name, name1, name2, c1, c6, c11)
SELECT
[_].[id_train],
[_].[time] as [time1],
[t4].[name],
[t5].[name] as [name1],
[t6].[name] as [name2],
[t7].[name] as [name3],
(
SELECT
Count(*)
FROM
[Wagons] [c]
WHERE
[_].[id_train] = [c].[id_train]
) as [c1],
(
SELECT
Sum([t2].[c2])
FROM
[Wagons] [c5]
INNER JOIN [WagonType] [t1] ON [c5].[id_wagonType] = [t1].[id_wagonType]
OUTER APPLY (
SELECT
Sum([c4].[weight_left_whell] + [c4].[weight_right_whell]) as [c2]
FROM
[Axles] [c4]
WHERE
[c5].[id_wagon] = [c4].[id_wagon]
) [t2]
WHERE
[_].[id_train] = [c5].[id_train] AND [t1].[type] = 1
) as [c6],
(
SELECT
Sum([t3].[c7])
FROM
[Wagons] [c10]
OUTER APPLY (
SELECT
Sum([c9].[weight_left_whell] + [c9].[weight_right_whell]) as [c7]
FROM
[Axles] [c9]
WHERE
[c10].[id_wagon] = [c9].[id_wagon]
) [t3]
WHERE
[_].[id_train] = [c10].[id_train]
) as [c11]
FROM
[Trains] [_]
INNER JOIN [Scales] [t4] ON [_].[id_scale] = [t4].[id_scale]
INNER JOIN [Direction] [t5] ON [_].[id_direction] = [t5].[id_direction]
INNER JOIN [WeightUnit] [t6] ON [_].[wu_id] = [t6].[id]
INNER JOIN [TrainType] [t7] ON [_].[id_type] = [t7].[id_type]
Понадобилось добавить условие:
var queryCriteria = from _ in
(from _ in serverContext.Trains
select new
{
Id = _.id_train,
DateTime = _.time,
Date = _.time.ToShortDateString(),
Time = _.time.ToShortTimeString(),
Scales = _.Scale.name,
Direction = _.Direction.name,
DatabaseName = _.WeightUnit.name,
TrainType = _.TrainType.name,
WagonsCount = _.Wagons.Count(),
WagonsWeight = _.Wagons.Where(w => w.WagonType.type).Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000,
TotalWeight = _.Wagons.Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000
})
where _.TotalWeight > 9000
select _;
И Sql получился такой:
(поля id_train1, time11, name1, name21, name31, name41)
куда делись еще 3 поля? (в прошлом запросе c1, c6, c11)
SELECT
[_1].[id_train] as [id_train1],
[_1].[time1] as [time11],
[_1].[name] as [name1],
[_1].[name2] as [name21],
[_1].[name3] as [name31],
[_1].[name4] as [name41]
FROM
(
SELECT
(
SELECT
Sum([t1].[c1])
FROM
[Wagons] [c3]
OUTER APPLY (
SELECT
Sum([c].[weight_left_whell] + [c].[weight_right_whell]) as [c1]
FROM
[Axles] [c]
WHERE
[c3].[id_wagon] = [c].[id_wagon]
) [t1]
WHERE
[_].[id_train] = [c3].[id_train]
) / 1000 as [c4],
[_].[id_train],
[_].[time] as [time1],
[t5].[name],
[t6].[name] as [name2],
[t7].[name] as [name3],
[t8].[name] as [name4],
(
SELECT
Count(*)
FROM
[Wagons] [c5]
WHERE
[_].[id_train] = [c5].[id_train]
) as [c6],
(
SELECT
Sum([t3].[c7])
FROM
[Wagons] [c10]
INNER JOIN [WagonType] [t2] ON [c10].[id_wagonType] = [t2].[id_wagonType]
OUTER APPLY (
SELECT
Sum([c9].[weight_left_whell] + [c9].[weight_right_whell]) as [c7]
FROM
[Axles] [c9]
WHERE
[c10].[id_wagon] = [c9].[id_wagon]
) [t3]
WHERE
[_].[id_train] = [c10].[id_train] AND [t2].[type] = 1
) as [c11],
(
SELECT
Sum([t4].[c12])
FROM
[Wagons] [c15]
OUTER APPLY (
SELECT
Sum([c14].[weight_left_whell] + [c14].[weight_right_whell]) as [c12]
FROM
[Axles] [c14]
WHERE
[c15].[id_wagon] = [c14].[id_wagon]
) [t4]
WHERE
[_].[id_train] = [c15].[id_train]
) as [c16]
FROM
[Trains] [_]
INNER JOIN [Scales] [t5] ON [_].[id_scale] = [t5].[id_scale]
INNER JOIN [Direction] [t6] ON [_].[id_direction] = [t6].[id_direction]
INNER JOIN [WeightUnit] [t7] ON [_].[wu_id] = [t7].[id]
INNER JOIN [TrainType] [t8] ON [_].[id_type] = [t8].[id_type]
) [_1]
WHERE
[_1].[c4] > 9000
+ при перечислении результата в отладке происходит такой Exception, в гриде оказывается пусто:
Index was outside the bounds of the array.
at System.Data.SqlClient.SqlDataReader.CheckDataIsReady(Int32 columnIndex, Boolean allowPartiallyReadColumn, Boolean permitAsync, String methodName)
at System.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn)
at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
at BLToolkit.Data.DataProvider.DataProviderBase.DataReaderBase`1.GetValue(Int32 i) in c:\Repository\3rdparty\bltoolkit\Source\Data\DataProvider\DataProviderBase.cs:line 301
at lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] )
at BLToolkit.Data.Linq.Query`1.<Map>d__60.MoveNext() in c:\Repository\3rdparty\bltoolkit\Source\Data\Linq\Query.cs:line 1041
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items() [Less]
|
Posted
about 13 years
ago
by
Terre <[email protected]>
Есть такой запрос:
var query = from _ in serverContext.Trains
select new
{
Id = _.id_train,
DateTime = _.time,
... [More]
Date = _.time.ToShortDateString(),
Time = _.time.ToShortTimeString(),
Scales = _.Scale.name,
Direction = _.Direction.name,
DatabaseName = _.WeightUnit.name,
TrainType = _.TrainType.name,
WagonsCount = _.Wagons.Count(),
WagonsWeight = _.Wagons.Where(w => w.WagonType.type).Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000,
TotalWeight = _.Wagons.Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000
};
который при помощи BLT преобразуется в SQL:
(поля id_train, time1, name, name1, name2, c1, c6, c11)
SELECT
[_].[id_train],
[_].[time] as [time1],
[t4].[name],
[t5].[name] as [name1],
[t6].[name] as [name2],
[t7].[name] as [name3],
(
SELECT
Count(*)
FROM
[Wagons] [c]
WHERE
[_].[id_train] = [c].[id_train]
) as [c1],
(
SELECT
Sum([t2].[c2])
FROM
[Wagons] [c5]
INNER JOIN [WagonType] [t1] ON [c5].[id_wagonType] = [t1].[id_wagonType]
OUTER APPLY (
SELECT
Sum([c4].[weight_left_whell] + [c4].[weight_right_whell]) as [c2]
FROM
[Axles] [c4]
WHERE
[c5].[id_wagon] = [c4].[id_wagon]
) [t2]
WHERE
[_].[id_train] = [c5].[id_train] AND [t1].[type] = 1
) as [c6],
(
SELECT
Sum([t3].[c7])
FROM
[Wagons] [c10]
OUTER APPLY (
SELECT
Sum([c9].[weight_left_whell] + [c9].[weight_right_whell]) as [c7]
FROM
[Axles] [c9]
WHERE
[c10].[id_wagon] = [c9].[id_wagon]
) [t3]
WHERE
[_].[id_train] = [c10].[id_train]
) as [c11]
FROM
[Trains] [_]
INNER JOIN [Scales] [t4] ON [_].[id_scale] = [t4].[id_scale]
INNER JOIN [Direction] [t5] ON [_].[id_direction] = [t5].[id_direction]
INNER JOIN [WeightUnit] [t6] ON [_].[wu_id] = [t6].[id]
INNER JOIN [TrainType] [t7] ON [_].[id_type] = [t7].[id_type]
Понадобилось добавить условие:
var queryCriteria = from _ in
(from _ in serverContext.Trains
select new
{
Id = _.id_train,
DateTime = _.time,
Date = _.time.ToShortDateString(),
Time = _.time.ToShortTimeString(),
Scales = _.Scale.name,
Direction = _.Direction.name,
DatabaseName = _.WeightUnit.name,
TrainType = _.TrainType.name,
WagonsCount = _.Wagons.Count(),
WagonsWeight = _.Wagons.Where(w => w.WagonType.type).Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000,
TotalWeight = _.Wagons.Sum(w => w.Axles.Sum(a => a.weight_left_whell + a.weight_right_whell)) / 1000
})
where _.TotalWeight > 9000
select _;
И Sql получился такой:
(поля id_train1, time11, name1, name21, name31, name41)
куда делись еще 3 поля? (в прошлом запросе c1, c6, c11)
SELECT
[_1].[id_train] as [id_train1],
[_1].[time1] as [time11],
[_1].[name] as [name1],
[_1].[name2] as [name21],
[_1].[name3] as [name31],
[_1].[name4] as [name41]
FROM
(
SELECT
(
SELECT
Sum([t1].[c1])
FROM
[Wagons] [c3]
OUTER APPLY (
SELECT
Sum([c].[weight_left_whell] + [c].[weight_right_whell]) as [c1]
FROM
[Axles] [c]
WHERE
[c3].[id_wagon] = [c].[id_wagon]
) [t1]
WHERE
[_].[id_train] = [c3].[id_train]
) / 1000 as [c4],
[_].[id_train],
[_].[time] as [time1],
[t5].[name],
[t6].[name] as [name2],
[t7].[name] as [name3],
[t8].[name] as [name4],
(
SELECT
Count(*)
FROM
[Wagons] [c5]
WHERE
[_].[id_train] = [c5].[id_train]
) as [c6],
(
SELECT
Sum([t3].[c7])
FROM
[Wagons] [c10]
INNER JOIN [WagonType] [t2] ON [c10].[id_wagonType] = [t2].[id_wagonType]
OUTER APPLY (
SELECT
Sum([c9].[weight_left_whell] + [c9].[weight_right_whell]) as [c7]
FROM
[Axles] [c9]
WHERE
[c10].[id_wagon] = [c9].[id_wagon]
) [t3]
WHERE
[_].[id_train] = [c10].[id_train] AND [t2].[type] = 1
) as [c11],
(
SELECT
Sum([t4].[c12])
FROM
[Wagons] [c15]
OUTER APPLY (
SELECT
Sum([c14].[weight_left_whell] + [c14].[weight_right_whell]) as [c12]
FROM
[Axles] [c14]
WHERE
[c15].[id_wagon] = [c14].[id_wagon]
) [t4]
WHERE
[_].[id_train] = [c15].[id_train]
) as [c16]
FROM
[Trains] [_]
INNER JOIN [Scales] [t5] ON [_].[id_scale] = [t5].[id_scale]
INNER JOIN [Direction] [t6] ON [_].[id_direction] = [t6].[id_direction]
INNER JOIN [WeightUnit] [t7] ON [_].[wu_id] = [t7].[id]
INNER JOIN [TrainType] [t8] ON [_].[id_type] = [t8].[id_type]
) [_1]
WHERE
[_1].[c4] > 9000
+ при перечислении результата в отладке происходит такой Exception, в гриде оказывается пусто:
Index was outside the bounds of the array.
at System.Data.SqlClient.SqlDataReader.CheckDataIsReady(Int32 columnIndex, Boolean allowPartiallyReadColumn, Boolean permitAsync, String methodName)
at System.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn)
at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
at BLToolkit.Data.DataProvider.DataProviderBase.DataReaderBase`1.GetValue(Int32 i) in c:\Repository\3rdparty\bltoolkit\Source\Data\DataProvider\DataProviderBase.cs:line 301
at lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] )
at BLToolkit.Data.Linq.Query`1.<Map>d__60.MoveNext() in c:\Repository\3rdparty\bltoolkit\Source\Data\Linq\Query.cs:line 1041
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items() [Less]
|
Posted
about 13 years
ago
by
mucks <[email protected]>
Баг есть в версии 4.1.10.2158, но он отсутствовал в версии 4.1.3.1859.
Суть — при повторном вызове запроса, который ранее делался с другим значением параметром, отправляется это предыдущее значение параметра, вместо переданного. Тестовый пример:
... [More]
class Program
{
class Item
{
public int Id { get; set; }
public int Hash { get; set; }
}
static string conString = @"Server=srv; Database=db; Integrated Security=true";
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
static void Test()
{
// значения, соответствующие имеющимся строкам в таблице
Item item1 = new Item { Id = 1, Hash = -345475078 };
Item item2 = new Item { Id = 2, Hash = -345475668 };
using (var db = GetManager())
{
ProcessItem(db, item1.Hash); // выводит на консоль Id переданного айтема "1"
ProcessItem(db, item2.Hash); // выводит на консоль Id предыдущего переданного айтема "1", должна вывести "2"
// на сервер в обоих случаях приходит запрос с одинаковым значением параметра
// exec sp_executesql N'SELECT
// [p].[ItemId]
// FROM [tbl_TestItemParameters] [p]
// WHERE EXISTS(
// SELECT * FROM [tbl_TestItems] [s]
// WHERE [s].[Hash] = @hash AND [s].[Id] = [p].[ItemId]
// )
// GROUP BY [p].[ItemId]
// ',N'@hash int',@hash=-345475078
}
}
static DbManager GetManager()
{
SqlConnection connection = new SqlConnection(conString);
DbManager db = new DbManager(connection);
return db;
}
static void ProcessItem(DbManager db, int hash)
{
var hashQuery = db.GetTable<TblItem>()
.Where(s => s.Hash == hash);
var groups = db.GetTable<TblItemParameter>()
.Where(p => hashQuery.Any(e => e.Id == p.ItemId))
.GroupBy(e => e.ItemId);
var res = groups.Select(g => g.Key.ToString()).ToArray();
Console.WriteLine(string.Join(", ", res));
}
}
[TableName(Name = "tbl_TestItems")]
public class TblItem
{
[Identity, PrimaryKey]
public int Id { get; set; }
public int Hash { get; set; }
}
[TableName(Name = "tbl_TestItemParameters")]
public class TblItemParameter
{
public int ItemId { get; set; }
public int ParameterId { get; set; }
public decimal Value { get; set; }
} [Less]
|
Posted
about 13 years
ago
by
mucks <[email protected]>
Баг есть в версии 4.1.10.2158, но он отсутствовал в версии 4.1.3.1859.
Суть — при повторном вызове запроса, который ранее делался с другим значением параметром, отправляется это предыдущее значение параметра, вместо переданного. Тестовый пример:
... [More]
class Program
{
class Item
{
public int Id { get; set; }
public int Hash { get; set; }
}
static string conString = @"Server=srv; Database=db; Integrated Security=true";
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
static void Test()
{
// значения, соответствующие имеющимся строкам в таблице
Item item1 = new Item { Id = 1, Hash = -345475078 };
Item item2 = new Item { Id = 2, Hash = -345475668 };
using (var db = GetManager())
{
ProcessItem(db, item1.Hash); // выводит на консоль Id переданного айтема "1"
ProcessItem(db, item2.Hash); // выводит на консоль Id предыдущего переданного айтема "1", должна вывести "2"
// на сервер в обоих случаях приходит запрос с одинаковым значением параметра
// exec sp_executesql N'SELECT
// [p].[ItemId]
// FROM [tbl_TestItemParameters] [p]
// WHERE EXISTS(
// SELECT * FROM [tbl_TestItems] [s]
// WHERE [s].[Hash] = @hash AND [s].[Id] = [p].[ItemId]
// )
// GROUP BY [p].[ItemId]
// ',N'@hash int',@hash=-345475078
}
}
static DbManager GetManager()
{
SqlConnection connection = new SqlConnection(conString);
DbManager db = new DbManager(connection);
return db;
}
static void ProcessItem(DbManager db, int hash)
{
var hashQuery = db.GetTable<TblItem>()
.Where(s => s.Hash == hash);
var groups = db.GetTable<TblItemParameter>()
.Where(p => hashQuery.Any(e => e.Id == p.ItemId))
.GroupBy(e => e.ItemId);
var res = groups.Select(g => g.Key.ToString()).ToArray();
Console.WriteLine(string.Join(", ", res));
}
}
[TableName(Name = "tbl_TestItems")]
public class TblItem
{
[Identity, PrimaryKey]
public int Id { get; set; }
public int Hash { get; set; }
}
[TableName(Name = "tbl_TestItemParameters")]
public class TblItemParameter
{
public int ItemId { get; set; }
public int ParameterId { get; set; }
public decimal Value { get; set; }
} [Less]
|
Posted
about 13 years
ago
by
Alllie <[email protected]>
Подскажите имеет ли смысл инкапсулировать слой доступа к данным? Что я под этим понимаю:
1. Инкапсулировать. Написать отдельный слой, звено, библиотеку и т.д., которая имеет внешний интерфейс. Другие слои, звенья и т.д. работаю с данными через этот
... [More]
слой
2. Не инкапсулировать. Использовать тот же BLToolkit и на странице, где мне нужно вывести все Persons писать типа
...db.GetTable<Person>().Where(...)... [Less]
|
Posted
about 13 years
ago
by
Alllie <[email protected]>
Подскажите имеет ли смысл инкапсулировать слой доступа к данным? Что я под этим понимаю:
1. Инкапсулировать. Написать отдельный слой, звено, библиотеку и т.д., которая имеет внешний интерфейс. Другие слои, звенья и т.д. работаю с данными через этот
... [More]
слой
2. Не инкапсулировать. Использовать тот же BLToolkit и на странице, где мне нужно вывести все Persons писать типа
...db.GetTable<Person>().Where(...)... [Less]
|
Posted
about 13 years
ago
by
Terre <[email protected]>
При отладке вываливается исключение:
A first chance exception of type 'System.TypeInitializationException' occurred in BLToolkit.4.dll
System.TypeInitializationException: Инициализатор типа "BLToolkit.Data.Sql.SqlProvider.BasicSqlProvider" выдал
... [More]
исключение. ---> System.Security.VerificationException: Операция может вызвать нестабильность при выполнении.
в BLToolkit.Data.Sql.SqlProvider.BasicSqlProvider..cctor()
Ах да, вываливается при такой штуке:
var x = (from _ in ctx.MyTable select _).ToList();
провайдер Sql2008DataProvider.
VS2010 SP1
Классы сгенерированы Т4:
public partial class ServerContext : DbManager
{
public Table<MyTable> MyTable { get { return this.GetTable<MyTable>(); } }
...
...
}
[TableName(Name="MyTable")]
public partial class MyTable : EditableObject<MyTable>
{
[Identity, PrimaryKey(1)] public int id { get; set; } // int(10)
public string name { get; set; } // nvarchar(32)
public string connection { get; set; } // ntext(1073741823)
[Nullable ] public DateTime? deletedate { get; set; } // datetime(3)
// FK_MyTableProperties_MyTable_BackReference
[Association(ThisKey="id", OtherKey="wu_id", CanBeNull=true)]
public IEnumerable<MyTableProperties> MyTableProperties { get; set; }
// FK_Units_MyTable_BackReference
[Association(ThisKey="id", OtherKey="wu_id", CanBeNull=true)]
public IEnumerable<Units> Units { get; set; }
}
P.S: Раньше работало нормально, BLToolkit версия последняя с Git (пробовал так же через nuget). [Less]
|
Posted
about 13 years
ago
by
Terre <[email protected]>
При отладке вываливается исключение:
A first chance exception of type 'System.TypeInitializationException' occurred in BLToolkit.4.dll
System.TypeInitializationException: Инициализатор типа "BLToolkit.Data.Sql.SqlProvider.BasicSqlProvider" выдал
... [More]
исключение. ---> System.Security.VerificationException: Операция может вызвать нестабильность при выполнении.
в BLToolkit.Data.Sql.SqlProvider.BasicSqlProvider..cctor()
Ах да, вываливается при такой штуке:
var x = (from _ in ctx.MyTable select _).ToList();
провайдер Sql2008DataProvider.
VS2010 SP1
Классы сгенерированы Т4:
public partial class ServerContext : DbManager
{
public Table<MyTable> MyTable { get { return this.GetTable<MyTable>(); } }
...
...
}
[TableName(Name="MyTable")]
public partial class MyTable : EditableObject<MyTable>
{
[Identity, PrimaryKey(1)] public int id { get; set; } // int(10)
public string name { get; set; } // nvarchar(32)
public string connection { get; set; } // ntext(1073741823)
[Nullable ] public DateTime? deletedate { get; set; } // datetime(3)
// FK_MyTableProperties_MyTable_BackReference
[Association(ThisKey="id", OtherKey="wu_id", CanBeNull=true)]
public IEnumerable<MyTableProperties> MyTableProperties { get; set; }
// FK_Units_MyTable_BackReference
[Association(ThisKey="id", OtherKey="wu_id", CanBeNull=true)]
public IEnumerable<Units> Units { get; set; }
}
P.S: Раньше работало нормально, BLToolkit версия последняя с Git (пробовал так же через nuget). [Less]
|
Posted
about 13 years
ago
by
MuxMux <[email protected]>
Всем доброго времени суток!
Пытаюсь имплементировать паттерн спецификация для слоя доступа к данным.
Есть вот такая сущность
[TableName("b_Input_Info")]
public abstract class InputInfo : Entity<InputInfo>
{
public abstract
... [More]
ProcessedState Processed { get; set; }
public abstract string Input { get; set; }
}
public enum ProcessedState
{
[MapValue(0)]Unprocessed,
[MapValue(1)]Successful,
[MapValue(2)]Error
}
public abstract class Entity<T> : EditableObject<T> where T : EditableObject<T>
{
[PrimaryKey, NonUpdatable]
public long? Id { get; set; }
}
Пытаюсь сделать композитную спецификацию "И":
public class AndSpecification<T> : BinarySpecification<T>
{
public AndSpecification(Specification<T> left, Specification<T> right) : base(left, right) { }
public override Expression<Func<T, bool>> IsSatisfiedBy()
{
var body = Expression.AndAlso(Left.IsSatisfiedBy().Body, Right.IsSatisfiedBy().Body);
var lambda = Expression.Lambda<Func<T, bool>>(body, Left.IsSatisfiedBy().Parameters);
return lambda;
}
}
public abstract class BinarySpecification<T> : Specification<T>
{
private readonly Specification<T> _left;
private readonly Specification<T> _right;
protected BinarySpecification(Specification<T> left, Specification<T> right)
{
_left = left;
_right = right;
}
public Specification<T> Left
{
get { return _left; }
}
public Specification<T> Right
{
get { return _right; }
}
}
public abstract class Specification<T>
{
public abstract Expression<Func<T, bool>> IsSatisfiedBy();
public static Specification<T> operator &(Specification<T> left, Specification<T> right)
{
return new AndSpecification<T>(left, right);
}
}
Хочу сделать выборку из InputInfo по двум критериям. Вот соответствующие спецификации:
public class InputSpecification : Specification<InputInfo>
{
private readonly string _input;
public InputSpecification(string input)
{
_input = input;
}
public override Expression<Func<InputInfo, bool>> IsSatisfiedBy()
{
return i => i.Input.Equals(_input);
}
}
public class ProcessedSpecification : Specification<InputInfo>
{
private readonly ProcessedState _processedState;
public ProcessedSpecification(ProcessedState processedState)
{
_processedState = processedState;
}
public override Expression<Func<InputInfo, bool>> IsSatisfiedBy()
{
return i => i.Processed == _processedState;
}
}
Использую все это хозяйство следующим образом:
IList<InputInfo> list = _dataAccessor.GetList(
new InputSpecification("Нормальный.xls") &
new ProcessedSpecification(ProcessedState.Successful));
где метод GetList:
public IList<T> GetList<T>(Specification<T> specification) where T : class
{
using (DbManager db = new DbManager("ODP", "Default"))
{
return db.GetTable<T>().Where(specification.IsSatisfiedBy()).ToList();
}
}
Так вот результатом объединения является ошибка "Cannnot convert i.Input to SQL query".
По отдельности критерии работают на ура. Т.е. проблема только в их объединении.
Буду рад любой помощи.
Заранее спасибо. [Less]
|