Добрый день!
Псевдокод:
class Entity
{
[Identity, PrimaryKey(1)]
public int Id { get; set; }
[Nullable]
public int? MemberId { get; set; }
[Nullable]
public int? MemberNo { get; set; }
[Nullable]
public string MemberName { get; set; }
}
q = from t in db.Entities select t;
// .. some filtering
// q = q.Where(...);
// q = q.Skip(200).Take(100);
var qr = from t in db.Entities
join r in q on t.Id equals r.Id
select new Entity
{
Id = t.Id,
MemberId = t.MemberId,
MemberNo = t.REntityMemberId.No,
MemberName = t.REntityMemberId.Name
};
var result = qr.ToList();
Так вот после выполнения оказывается что MemberNo==0, MemberName=="" там где MemberId=NULL. При этом SQL запросы генерируются правильные, проблема как я понимаю в маппинге. Как бороться?
Здравствуйте, fddima, Вы писали:
Ясно что дело не ясное.
Код уходит в MappingSchema.cs в метод например ConvertToInt32, который превращает честный DBNull в значение по умолчанию. А по стек трейсу ничего нужного увидеть не удалось.
Покопавшись — понял, что проблема возникает в ExpressionParser.QueryBuilder.cs:1106. Это метод
1069: Expression BuildField(Expression ma, ISqlExpression expr, int[] idx)
А проблема возникает, потому что не учитывается тип левого операнда (приёмника), ( ??? или не учитывается cast к nullable в экспрешн дереве, или если и он и происходит — то поздно), в любом случае полученные данные теряются.
Таким образом условно из примера выше:
MemberNo = t.REntityMemberId.No
, мы маппим из БД значение к типу представленному полем t.REntityMemberId.No который действительно честный Int32, но левый MemberNo — Nullable<Int32>, и из БД к нам приходит DBNull.Value.
Имхо правильнее было бы маппить к типу левого операнда, ( ??? или не игнорировать cast в дереве).
Правда как это исправить — я не очень знаю.
С другой стороны оба поведения наверное не слишком очевидны.