var res = from rc in db.GetTable<ResourceCount>()
join li in db.GetTable<LookupInterface>() on rc.Id equals li.Stock.Id
where rc.StockType == StockName.ResourceCount
select rc;
var list = res.ToList();
генерит вот это:
SELECT
[rc].[StockType],
[rc].[Amount],
[rc].[IsActive],
[rc].[AccountStockId] as [Id],
[rc].[CategoryId] as [StockCategory_Id],
[rc].[SuperAccountId] as [Owner_Id]
FROM
[AccountStock] [rc]
INNER JOIN [LookupInterface] [t1] ON [rc].[AccountStockId] = [t1].[LookupLink]
WHEREConvert(Int, (
SELECT
*
)) = 48
а раньше было так:
WHERE Cast(rc.StockType as Int) = 48
P.S. на счет того что был cast а не convert я не уверен
P.P.S. rc.StockType — enum
Здравствуйте, ili, Вы писали:
ili>проапдейтился и кой чего сломалось:
и еще несколько схожая ситуёвина:
вот такой запрос валится
var zones = (from z in db.GetTable<PaidZoneVisit>()
join o in db.GetTable<SuperAccount>() on z.Owner.Id equals o.Id
where z.Amount > 0
&& o.Type == SuperAccountType.Client
select z).ToList();
в ExpressionParser
ISqlExpression ParseSubQuery(ParseInfo expr, params QuerySource[] queries)
{
ParsingTracer.WriteLine(expr);
ParsingTracer.WriteLine(queries);
ParsingTracer.IncIndentLevel();
var parentQueries = queries.Select(q => new ParentQuery { Parent = q, Parameter = q.Lambda.Parameters.FirstOrDefault() }).ToList();
Здравствуйте, ili, Вы писали:
ili>проапдейтился и кой чего сломалось:
ili>вот это:
ili>
ili>var res = from rc in db.GetTable<ResourceCount>()
ili> join li in db.GetTable<LookupInterface>() on rc.Id equals li.Stock.Id
ili> where rc.StockType == StockName.ResourceCount
ili> select rc;
ili>var list = res.ToList();
ili>
ili>генерит вот это:
Не воспроизводится. Можно структуру объектов посмотреть. Особенно интересно что такое li.Stock.Id.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, ili, Вы писали:
ili>и еще несколько схожая ситуёвина:
Этот тоже не воспроизводиться. Но я немного подкрутил работу с энумераторами, может быть поможет. Если нет, то желательно получить код классов или минимально упрощённый пример, на котором это проявляется.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Этот тоже не воспроизводиться. Но я немного подкрутил работу с энумераторами, может быть поможет. Если нет, то желательно получить код классов или минимально упрощённый пример, на котором это проявляется.
не спасли 300р отца русской демократии
ща тесты делать буду, которые воспроизводят.
так, а чего поставить надо, чтобы UnitTests.Linq.dll загружалась нормально, а то nUnit говорит FileNotFoundException — не могу загрузить сборку UnitTests.Linq.dll или один зависимый от них компонент (про образ виртуальный я помню, но мен так, в общеобразовательном плане дополнительно интересно).
IT>Этот тоже не воспроизводиться. Но я немного подкрутил работу с энумераторами, может быть поможет. Если нет, то желательно получить код классов или минимально упрощённый пример, на котором это проявляется.
код ниже, а в краце, все упипается в то, что TestEntity и SuperAccount наследники IEnumerable<T>, как только убираешь это наследование, летает как трофейный мерседес.
[TestFixture]
public class Tests1
{
public class Entity
{
public int Id { get; set; }
}
public enum TestEntityType : byte { Type1, Type2 }
[MapField("LookupEntityId", "Id")]
[MapField("LookupLink", "InnerEnity.Id")]
public class LookupEntity : Entity
{
public Entity InnerEnity { get; set; }
public TestEntityType InnerEntityType { get; set; }
}
[TableName("TestEntity")]
[MapField("TestEntityBaseId", "Id")]
[MapField("SuperAccountId", "Owner.Id")]
public class TestEntityBase : Entity
{
public TestEntityType EntityType { get; set; }
public SuperAccount Owner { get; set; }
public decimal Amount { get; set; }
}
public class TestEntity : TestEntityBase, IEnumerable<object>
{
#region IEnumerable<object> Members
public IEnumerator<object> GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
[TableName("TestEntity2")]
public class TestEntity2 : TestEntityBase
{
}
public enum SuperAccountType { Client, Organization }
public class SuperAccount : Entity, IEnumerable<object>
{
public List<Entity> InnerAccounts { get; set; }
public SuperAccountType Type { get; set; }
#region IEnumerable<object> Members
public IEnumerator<object> GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
[Test]
public void WrongQueryTest()
{
using (var db = new DbManager())
{
try
{
var res = from rc in db.GetTable<TestEntity>()
join li in db.GetTable<LookupEntity>() on rc.Id equals li.InnerEnity.Id
where rc.EntityType == TestEntityType.Type1
select rc;
res.ToList();
}
finally
{
Console.WriteLine(db.LastQuery);
}
}
}
[Test]
public void NRETest()
{
using (var db = new DbManager())
{
var zones = (from z in db.GetTable<TestEntity2>()
join o in db.GetTable<SuperAccount>() on z.Owner.Id equals o.Id
where z.Amount > 0
&& o.Type == SuperAccountType.Client
select z).ToList();
}
}
}
Здравствуйте, AndrewVK, Вы писали:
AVK>.NET драйвера всех используемых внешних СУБД — ODP для Оракля, DB2, Informix, MySql, FB, Sybase. Может еще какую забыл.
спс, вот что-то подобное я и подозревал...
хорошобы добавить ссылки откуда качать, дабы гугл не перенапрягать, либо в текстик в редистре как для оракула, либо в вики, которая сейчас лежит, там даж раздел был про поддерживаемые провайдеры... его еще и дополнить можно
Здравствуйте, ili, Вы писали:
ili>код ниже, а в краце, все упипается в то, что TestEntity и SuperAccount наследники IEnumerable<T>, как только убираешь это наследование, летает как трофейный мерседес.
Понятно. Тогда ничего удивительного, BLT не может выявить разницу межу скалярным полем и списочным, если это IEnumerable. Какие-нибудь идеи как это распознать?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Понятно. Тогда ничего удивительного, BLT не может выявить разницу межу скалярным полем и списочным, если это IEnumerable. Какие-нибудь идеи как это распознать?
эээ... месяц назад этот код работал, у меня с ним релиз продукта есть точную ревизию не скажу, но последний апдейт (до того как этот код сломался) я делал где-то в декабре.
да и чего тут распозновать, везде скаляры.
где-то, что-то не так при разборе лямбд в where, когда тот же join on equals разбирается и строится четко.
эт ярко видно на WrongQueryTest, где генерится кривой код именно в WHERE.
В NRETest разбор WHERE вообще не проходит, по ходу из-за того, что там два условия...
на работу приду — проверю.
[Test]
public void WrongQueryTest()
{
using (var db = new DbManager())
{
try
{
var res = from rc in db.GetTable<TestEntity>()
join li in db.GetTable<LookupEntity>() on rc.Id equals li.InnerEnity.Id //скалярwhere rc.EntityType == TestEntityType.Type1 //скалярselect rc; // IEnumerable но работает правильно - поля сгенерены;
res.ToList();
}
finally
{
Console.WriteLine(db.LastQuery);
}
}
}
[Test]
public void NRETest()
{
using (var db = new DbManager())
{
var zones = (from z in db.GetTable<TestEntity2>()
join o in db.GetTable<SuperAccount>() on z.Owner.Id equals o.Id //скалярwhere z.Amount > 0 //скаляр
&& o.Type == SuperAccountType.Client //скалярselect z /* до этого даже не доходит */).ToList();
}
}
Здравствуйте, ili, Вы писали:
ili>Здравствуйте, IT, Вы писали:
IT>>Понятно. Тогда ничего удивительного, BLT не может выявить разницу межу скалярным полем и списочным, если это IEnumerable. Какие-нибудь идеи как это распознать?
ili>эээ... месяц назад этот код работал, у меня с ним релиз продукта есть точную ревизию не скажу, но последний апдейт (до того как этот код сломался) я делал где-то в декабре.
Я недавно менял в одном месте List<T> на IEnumerable<T>, т.к. последнее правильнее. По-этому и сломалось.
ili>да и чего тут распозновать, везде скаляры.
Логика то простая. Раз объект наследуется от IEnumerable<T>, значит это списочный объект. Нужна какая-то дополнительная проверка.
... << RSDN@Home 1.2.0 alpha 4 rev. 1425>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, ili, Вы писали:
IT>>Понятно. Тогда ничего удивительного, BLT не может выявить разницу межу скалярным полем и списочным, если это IEnumerable. Какие-нибудь идеи как это распознать?
В общем, я долго думал и ничего кроме IgnoreIEnumerable атрибута не придумал. Вещать на все классы, которые испльзуются как скаляры. Обе баги вроде полечились.
... << RSDN@Home 1.2.0 alpha 4 rev. 1425>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Логика то простая. Раз объект наследуется от IEnumerable<T>, значит это списочный объект. Нужна какая-то дополнительная проверка.
эээ... поясни для тех кто в танке и не в тренде:
var res = from rc in db.GetTable<TestEntity>()
join li in db.GetTable<LookupEntity>() on rc.Id equals li.InnerEnity.Id //скалярwhere rc.EntityType == TestEntityType.Type1 //скалярselect rc; // IEnumerable но работает правильно - поля сгенерены;
где здесь IEnumerable<T> кроме select rc?
я ввиду, тойже, малоопытасти не знаю как правильно выразить join но :
везде скаляры...
я так, интуитивно думаю, что валиться на такой лямбде rc => rc.EntityType == TestEntityType.Type1
ну так сверять то надо не вход лямбды, а операнды, а в операндах четкие скаляры...
да и L2O работает без приседаний:
[Test]
public void Linq2ObjectTest()
{
var tel = new List<TestEntity>();
var lel = new List<LookupEntity>();
tel.Add(new TestEntity() { EntityType = TestEntityType.Type1, Id = 1 });
tel.Add(new TestEntity() { EntityType = TestEntityType.Type1, Id = 2 });
tel.Add(new TestEntity() { EntityType = TestEntityType.Type1, Id = 3 });
lel.Add(new LookupEntity() { InnerEnity = tel[0] });
lel.Add(new LookupEntity() { InnerEnity = tel[1] });
var res = from rc in tel
join li in lel on rc.Id equals li.InnerEnity.Id
where rc.EntityType == TestEntityType.Type1
select rc;
var rel = res.ToList();
Assert.AreEqual(2, rel.Count);
Assert.That(object.ReferenceEquals(tel[0], rel[0]));
Assert.That(object.ReferenceEquals(tel[1], rel[1]));
}
Здравствуйте, ili, Вы писали:
ili>эээ... поясни для тех кто в танке и не в тренде:
ili>
ili>var res = from rc in db.GetTable<TestEntity>()
ili> join li in db.GetTable<LookupEntity>() on rc.Id equals li.InnerEnity.Id //скаляр
ili> where rc.EntityType == TestEntityType.Type1 //скаляр
ili> select rc; // IEnumerable но работает правильно - поля сгенерены;
ili>
Выделенное.
ili>да и L2O работает без приседаний:
В данном случае может и работает. Будем считать, что BLT в такой ситуации не работает бай дизайн.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>В данном случае может и работает. Будем считать, что BLT в такой ситуации не работает бай дизайн.
хозяин — барин... но с моей, профанской точки зрения простого пользователя, BLT неправильно в этом случае парсит выражение — если работает в L2O то и в BLT должно, типа догмат юзера да и абсолютно неожиданый результат получается...
Здравствуйте, IT, Вы писали:
IT>В общем, я долго думал и ничего кроме IgnoreIEnumerable атрибута не придумал. Вещать на все классы, которые испльзуются как скаляры. Обе баги вроде полечились.
спс, только есть такой вопрос — а с применеием этого аттрибута, какие запросы могут сломаться?
Здравствуйте, ili, Вы писали:
ili>хозяин — барин... но с моей, профанской точки зрения простого пользователя, BLT неправильно в этом случае парсит выражение — если работает в L2O то и в BLT должно, типа догмат юзера
L2S и линк в BLT все таки не одно и то же, BLT обладает рядом дополнительных возможностей и особенностей. И иногда таки да, это особенности и возможности приводят к ощутимой разнице в поведении. Это нормально для продуктов подобной сложности.
... << RSDN@Home 1.2.0 alpha 4 rev. 1424 on Windows 7 6.1.7600.0>>