Query with using paired EntitySets twice (e.g. EntityA.EntitiesB.SelectMany(entityB => entityB.EntitiesA) may return empty set. Look at the example below:
namespace Sample
{
using System;
using Xtensive.Orm;
using Xtensive.Orm.Configuration;
using System.Linq;
using Domain = Xtensive.Orm.Domain;
[HierarchyRoot]
public class MasterEntity : Entity
{
[Key] [Field] public Guid MasterId { get; }
[Field] public EntitySet<SlaveEntity> Slaves { get; set; }
}
[HierarchyRoot]
public class SlaveEntity : Entity
{
[Key] [Field] public Guid SlaveId { get; }
[Association(PairTo = nameof(MasterEntity.Slaves))]
[Field] public EntitySet<MasterEntity> Masters { get; set; }
}
class Program
{
static void Main()
{
var dc = new DomainConfiguration("sqlserver", "Data Source=.; Initial Catalog=DO40-Tests;Connection Timeout=300;Integrated Security = true;");
dc.Types.Register(typeof(Program).Assembly);
dc.UpgradeMode = DomainUpgradeMode.Recreate;
var sessionConfiguration = new SessionConfiguration(SessionOptions.AutoActivation | SessionOptions.ServerProfile);
using (var domain = Domain.Build(dc))
{
using (var session = domain.OpenSession(sessionConfiguration))
using (session.Activate())
using (session.OpenTransaction())
{
PopulateData();
ShowBug();
}
}
Console.ReadKey(true);
}
private static void PopulateData()
{
var master = new MasterEntity();
master.Slaves.Add(new SlaveEntity());
}
private static void ShowBug()
{
var targetMaster = Query.All<MasterEntity>().First();
var targetSlave = Query.All<SlaveEntity>().First();
var queryMasters = Query.All<MasterEntity>()
.Any(o => o.Slaves.SelectMany(t => t.Masters).Contains(targetMaster));
var inMemoryMasters = Query.All<MasterEntity>().AsEnumerable()
.Any(o => o.Slaves.SelectMany(t => t.Masters).Contains(targetMaster));
Console.WriteLine($"Masters: {queryMasters} - {inMemoryMasters}");
var querySlaves = Query.All<SlaveEntity>()
.Any(o => o.Masters.SelectMany(t => t.Slaves).Contains(targetSlave));
var inMemorySlaves = Query.All<SlaveEntity>().AsEnumerable()
.Any(o => o.Masters.SelectMany(t => t.Slaves).Contains(targetSlave));
Console.WriteLine($"Slaves: {querySlaves} - {inMemorySlaves}");
}
}
}
Query for slaves returns different results for database query and inmemory query:
Masters: True - True
Slaves: False - True
Generated SQL queries contain strange where clause after joins of entity table with entityset tables ([b] refers to table of EntitySet):
For Masters:
([b].[MasterEntity] = [b].[MasterEntity])
For Slaves:
([b].[SlaveEntity] = [b].[MasterEntity])
asked
Apr 12 '19 at 10:13
Platonov
5●7●7●8