Hi

Here we go. Three tests. DO 4.6.2

Model:

/// <summary>
/// Place
/// </summary>
[HierarchyRoot]
[Serializable]
public class Place : Entity
{
    /// <summary>
    /// Id
    /// </summary>
    [Field, Key]
    public int Id { get; private set; }

    /// <summary>
    /// Name
    /// </summary>
    [Field]
    public string Name { get; set; }
}

Test:

using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Project1.Model;

using Xtensive.Orm;
using Xtensive.Orm.Configuration;

[TestClass]
public class TestEntities
{
    protected Domain domain;
    protected Session session;
    protected TransactionScope transactionScope;

    [TestInitialize()]
    public virtual void Initialize()
    {
        var config = new DomainConfiguration
        {
            ConnectionInfo = new ConnectionInfo("sqlserver://localhost/DO40-Tests")
        };

        config.Types.Register(this.GetType().Assembly);
        config.Name = "Default";
        config.UpgradeMode = UpgradeMode;
        domain = Domain.Build(config);
        CreateBase();
        OpenTransactions();
    }
    protected virtual void CreateBase()
    {
        if (this.domain.Configuration.UpgradeMode != DomainUpgradeMode.Recreate)
        {
            return;
        }

        using (var baseSession = this.domain.OpenSession())
        {
            using (baseSession.Activate())
            using (var baseTransactionScope = baseSession.OpenTransaction())
            {
                var somePlace = new Place() { Name = "SomePlace" };
                var otherPlace = new Place() { Name = "OtherPlace" };

                baseTransactionScope.Complete();
            }
        }
    }

    protected virtual void OpenTransactions()
    {
        session = domain.OpenSession();
        transactionScope = session.OpenTransaction();
    }

    [TestCleanup()]
    public void Cleanup()
    {
        CloseTransactions();
    }
    protected virtual void CloseTransactions()
    {
        transactionScope.Dispose();
        session.Dispose();
    }
    protected virtual DomainUpgradeMode UpgradeMode
    {
        get { return DomainUpgradeMode.Recreate; }
    }

    [TestMethod]
    public void TestDistinct()
    {
        var query = from e in session.Query.All<Place>()
                    from i in session.Query.All<Place>()
                    select e.Id == i.Id;

        Assert.AreEqual(4, query.Count());

       var first = query.Where(e => e).Select(e => e);

        Assert.AreEqual(2, first.Count());

        var second = query.Where(e => !e).Select(e => e);

        Assert.AreEqual(2, second.Count());

        var firstDistinct = first.Distinct();

        Assert.AreEqual(1, firstDistinct.Count());

        var secondDistinct = second.Distinct();

        Assert.AreEqual(1, secondDistinct.Count());

       var distinct = query.Distinct();

        Assert.AreEqual(2, distinct.Count());
    }

    [TestMethod]
    public void TestJoin()
    {
        var tmp = new List<int>() {1,1};

        var query = from e in session.Query.All<Place>()
                    join i in tmp on e.Id equals i into j
                    select e;

        query.Count();
    }

    [TestMethod]
    public void TestSelect()
    {
        var tmp = new List<int>() { 1, 1 };

        var query = from e in session.Query.All<Place>()
                    from i in tmp
                    select e;

        query.Count();
    }
}

SQL distinct queries:

SELECT  COUNT_BIG(*) AS [c01umn]
FROM    ( SELECT DISTINCT
                    [a].[Id] ,
                    [b].[Id] AS [#a.Id]
          FROM      [dbo].[Place] [a]
                    INNER JOIN [dbo].[Place] [b] ON ( CAST(1 AS BIT) <> 0 )
          WHERE     ( [a].[Id] = [b].[Id] )
        ) [c];

SELECT  COUNT_BIG(*) AS [c01umn]
FROM    ( SELECT DISTINCT
                    [a].[Id] ,
                    [b].[Id] AS [#a.Id]
          FROM      [dbo].[Place] [a]
                    INNER JOIN [dbo].[Place] [b] ON ( CAST(1 AS BIT) <> 0 )
          WHERE     ( NOT ( [a].[Id] = [b].[Id] )
                    )
        ) [c];

SELECT  COUNT_BIG(*) AS [c01umn]
FROM    ( SELECT DISTINCT
                    [a].[Id] ,
                    [b].[Id] AS [#a.Id]
          FROM      [dbo].[Place] [a]
                    INNER JOIN [dbo].[Place] [b] ON ( CAST(1 AS BIT) <> 0 )
        ) [c];

Exception in TestJoin:

Xtensive.Orm.QueryTranslationException: Unable to translate 'Query.All().GroupJoin(
  $<IEnumerable<Int32>>(System.Collections.Generic.List`1[System.Int32]),
  e => e.Id,
  i => i,
  (e, j) => e
).Count()' expression. See inner exception for details. ---> System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.TypedConstantExpression' to type 'Xtensive.Orm.Linq.Expressions.ProjectionExpression'.

Exception in TestSelect:

Xtensive.Orm.SyntaxErrorException: SQL error occured.
SQL error details 'Type: SyntaxError;'
Query 'CREATE TABLE [dbo].[#Tmp_240a61f6-9432-4998-8e66-a46362dd0d2b] ()'
Original message 'Incorrect syntax near ')'.' ---> System.Data.SqlClient.SqlException: Incorrect syntax near ')'.

GroupBy works. For example, if Place contains three elements

        var query = from e in session.Query.All<Place>()
                    from i in session.Query.All<Place>()
                    select new { item = e, eq = e.Id == i.Id };

        var keys = query.GroupBy(i => new { i.item, i.eq });

        Assert.AreEqual(session.Query.All<Place>().Count() * 2, keys.Count());
        Assert.AreEqual(session.Query.All<Place>().Count() * 2, query.Distinct().Count());

keys.Count() generate this SQL query and return 6 elems

SELECT  COUNT_BIG(*) AS [c01umn1]
FROM    ( SELECT    [a].[Id] AS [Id] ,
                    [a].[TypeId] AS [TypeId] ,
                    [a].[c01umn] AS [c01umn]
          FROM      ( SELECT    [b].[Id] ,
                                102 AS [TypeId] ,
                                [b].[Name] ,
                                [c].[Id] AS [#a.Id] ,
                                102 AS [#a.TypeId] ,
                                [c].[Name] AS [#a.Name] ,
                                CAST(( CASE WHEN ( [b].[Id] = [c].[Id] ) THEN 1
                                            ELSE 0
                                       END ) AS BIT) AS [c01umn]
                      FROM      [dbo].[Place] [b]
                                INNER JOIN [dbo].[Place] [c] ON ( CAST(1 AS BIT) <> 0 )
                    ) [a]
          GROUP BY  [a].[Id] ,
                    [a].[TypeId] ,
                    [a].[c01umn]
        ) [d]
        INNER JOIN [dbo].[Place] [e] ON ( [d].[Id] = [e].[Id] );

query.Distinct().Count() return 9 elems

asked Feb 21 '13 at 00:02

Anton%20Guschin's gravatar image

Anton Guschin
73303035

edited Feb 21 '13 at 00:45

With 4.6.3 similar results

(Feb 21 '13 at 00:09) Anton Guschin Anton%20Guschin's gravatar image

Hello Anton, thank you for you message.

We'll check provided queries.

I can say now about Distinct() and Select() problems: currently DataObjects.Net evaluates all selects lazily, this in particular means that .Select(...).Distinct() is treated like Distinct().Select(...) which might be completely different query.

(Feb 21 '13 at 05:27) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

One Answer:

Fixes would be available in DataObjects.Net 4.5.8/4.6.4

Distinct handling is tricky however. Generally it's advisable to move Select() call as close to Distinct() as possible.

answered Feb 23 '13 at 05:26

Denis%20Krjuchkov's gravatar image

Denis Krjuchkov
179325

edited Feb 23 '13 at 05:42

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA