Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query
{
using System.Data.Entity.Core.Metadata.Edm;
using Xunit;
public class FunctionTests : TestBase
{
private static readonly MetadataWorkspace workspace = QueryTestHelpers.CreateMetadataWorkspace(
ProductModel.csdl, ProductModel.ssdl, ProductModel.msl);
[Fact]
public void Inline_function_count_Products()
{
var query =
@"Function CountProducts(products Collection(ProductModel.Product)) as
(count(select value 1 from products))
select gkey, CountProducts(GroupPartition(P))
FROM ProductContainer.Products as P
Group By P.ProductName as gkey";
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ProductName],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[Extent1].[ProductName] AS [K1],
COUNT(1) AS [A1]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[Discontinued] IN (0,1)
GROUP BY [Extent1].[ProductName]
) AS [GroupBy1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Inline_functions_MaxProductId_and_MinProductId()
{
var query =
@"Function MinProductId(products Collection(ProductModel.Product)) as
(min(select value pp.ProductId from products as pp))
Function MaxProductId(products Collection(ProductModel.Product)) as
(max(select value pp.ProductId from products as pp))
select gkey, MinProductId(GroupPartition(P)), MaxProductId(GroupPartition(P))
FROM ProductContainer.Products as P
Group By P.ProductName as gkey";
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ProductName],
[GroupBy1].[A1] AS [C2],
[GroupBy1].[A2] AS [C3]
FROM ( SELECT
[Extent1].[ProductName] AS [K1],
MIN([Extent1].[ProductID]) AS [A1],
MAX([Extent1].[ProductID]) AS [A2]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[Discontinued] IN (0,1)
GROUP BY [Extent1].[ProductName]
) AS [GroupBy1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Inline_function_MaxMinProductId()
{
var query =
@"Function MaxMinProductId(products Collection(ProductModel.Product)) as
(
max(select value pp.ProductId from products as pp) -
min(select value pp.ProductId from products as pp)
)
select gkey, MaxMinProductId(GroupPartition(p))
FROM ProductContainer.Products as P
Group By P.ProductName as gkey";
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ProductName],
[GroupBy1].[A1] - [GroupBy1].[A2] AS [C2]
FROM ( SELECT
[Extent1].[ProductName] AS [K1],
MAX([Extent1].[ProductID]) AS [A1],
MIN([Extent1].[ProductID]) AS [A2]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[Discontinued] IN (0,1)
GROUP BY [Extent1].[ProductName]
) AS [GroupBy1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Inline_function_one_level_above()
{
var query =
@"Function MaxProductId(products Collection(ProductModel.Product)) as
(
max(select value pp.ProductId from products as pp)
)
select i.gkey, (MaxProductId(i.groupProducts))
from (
select gkey as gkey, GroupPartition(P) as groupProducts
FROM ProductContainer.Products as P
Group By P.ProductName as gkey
) as i";
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ProductName],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[Extent1].[ProductName] AS [K1],
MAX([Extent1].[ProductID]) AS [A1]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[Discontinued] IN (0,1)
GROUP BY [Extent1].[ProductName]
) AS [GroupBy1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Inline_function_MaxInt()
{
var query =
@"Function MaxInt(i Collection(Int32)) as (max(i))
select gkey, MaxInt(groupPartition(a))
FROM {1,1,2,2,2} as a
Group By a as gkey";
var expectedSql =
@"SELECT
[GroupBy1].[K1] AS [C1],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[UnionAll4].[C1] AS [K1],
MAX([UnionAll4].[C1]) AS [A1]
FROM (SELECT
[UnionAll3].[C1] AS [C1]
FROM (SELECT
[UnionAll2].[C1] AS [C1]
FROM (SELECT
[UnionAll1].[C1] AS [C1]
FROM (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
UNION ALL
SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
UNION ALL
SELECT
2 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
UNION ALL
SELECT
2 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable4]) AS [UnionAll3]
UNION ALL
SELECT
2 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable5]) AS [UnionAll4]
GROUP BY [UnionAll4].[C1]
) AS [GroupBy1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Inline_aggregate_funtion_MinProductId()
{
var query =
@"Function MinProductId(products Collection(ProductModel.Product)) as
(
anyelement(select value min(pp.ProductId) from products as pp)
)
select gkey, MinProductId(GroupPartition(P))
FROM ProductContainer.Products as P
Group By P.ProductName as gkey";
var expectedSql =
@"SELECT
1 AS [C1],
[Project2].[ProductName] AS [ProductName],
[Project2].[C1] AS [C2]
FROM ( SELECT
[Distinct1].[ProductName] AS [ProductName],
(SELECT
MIN([Extent2].[ProductID]) AS [A1]
FROM [dbo].[Products] AS [Extent2]
WHERE ([Extent2].[Discontinued] IN (0,1)) AND (([Distinct1].[ProductName] = [Extent2].[ProductName]) OR (([Distinct1].[ProductName] IS NULL) AND ([Extent2].[ProductName] IS NULL)))) AS [C1]
FROM ( SELECT DISTINCT
[Extent1].[ProductName] AS [ProductName]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[Discontinued] IN (0,1)
) AS [Distinct1]
) AS [Project2]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query
{
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Xunit;
public class LeftOuterJoinEliminationContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<DocumentDetail> DocumentDetails { get; set; }
}
public class Customer
{
[Key]
public int? CustomerId { get; set; }
public int PersonId { get; set; }
}
public class Document
{
[Key]
public int? DocumentId { get; set; }
public int? CustomerId { get; set; }
[ForeignKey("CustomerId")]
public Customer Customer { get; set; }
}
public class DocumentDetail
{
[Key]
public int? DocumentDetailId { get; set; }
public int? DocumentId { get; set; }
[ForeignKey("DocumentId")]
public Document Document { get; set; }
}
public class JoinEliminationTests : FunctionalTestBase
{
[Fact]
public static void LeftOuterJoin_duplicates_are_eliminated()
{
const string expectedSql =
@"SELECT
[Extent1].[DocumentDetailId] AS [DocumentDetailId],
[Extent1].[DocumentId] AS [DocumentId]
FROM [dbo].[DocumentDetails] AS [Extent1]
LEFT OUTER JOIN [dbo].[Documents] AS [Extent2] ON [Extent1].[DocumentId] = [Extent2].[DocumentId]
LEFT OUTER JOIN [dbo].[Customers] AS [Extent3] ON [Extent2].[CustomerId] = [Extent3].[CustomerId]
WHERE [Extent3].[PersonId] IN (1,2)";
using (var context = new LeftOuterJoinEliminationContext())
{
var query = context.DocumentDetails.Where(x => x.Document.Customer.PersonId == 1 || x.Document.Customer.PersonId == 2);
QueryTestHelpers.VerifyQuery(query, expectedSql);
}
}
}
}

View File

@@ -0,0 +1,320 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Linq;
using Xunit;
public enum Genre
{
Action,
Humor,
Fantasy,
}
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public Genre? Genre { get; set; }
public AuthorName Author { get; set; }
}
public class AuthorName
{
public string First { get; set; }
public string Last { get; set; }
}
public class EnumerableContainsTests : FunctionalTestBase
{
public class UnicodeContext : DbContext
{
public DbSet<Book> Books { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>().Property(p => p.Title).IsUnicode(true);
}
}
public class NonUnicodeContext : DbContext
{
public DbSet<Book> Books { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>().Property(p => p.Title).IsUnicode(false);
}
}
[Fact]
public static void EnumerableContains_with_unicode_string_and_store_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE ([Extent1].[Title] IN (N'Title1', N'Title2'))
OR ([Extent1].[Title] IS NULL)";
var array = new[] { "Title1", "Title2", null };
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = from book in context.Books
where array.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_unicode_string_and_csharp_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE (([Extent1].[Title] IN (N'Title1', N'Title2')) AND ([Extent1].[Title] IS NOT NULL))
OR ([Extent1].[Title] IS NULL)";
var array = new[] { "Title1", "Title2", null };
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = from book in context.Books
where array.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_non_unicode_string_and_store_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE ([Extent1].[Title] IN ('Title1', 'Title2'))
OR ([Extent1].[Title] IS NULL)";
var array = new[] { "Title1", "Title2", null };
using (var context = new NonUnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = from book in context.Books
where array.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_non_unicode_string_and_csharp_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE (([Extent1].[Title] IN ('Title1', 'Title2')) AND ([Extent1].[Title] IS NOT NULL))
OR ([Extent1].[Title] IS NULL)";
var array = new[] { "Title1", "Title2", null };
using (var context = new NonUnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = from book in context.Books
where array.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_enum_and_store_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE ([Extent1].[Genre] IN (1,2))
OR ([Extent1].[Genre] IS NULL)";
var array = new[] { Genre.Humor, Genre.Fantasy, default(Genre?) };
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = from book in context.Books
where array.Contains(book.Genre)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_enum_and_csharp_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE (([Extent1].[Genre] IN (1,2)) AND ([Extent1].[Genre] IS NOT NULL))
OR ([Extent1].[Genre] IS NULL)";
var array = new[] { Genre.Humor, Genre.Fantasy, default(Genre?) };
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = from book in context.Books
where array.Contains(book.Genre)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_complex_type_throws_NotSupportedException()
{
var array = new[] { new AuthorName(), new AuthorName() };
using (var context = new UnicodeContext())
{
var query = from book in context.Books
where array.Contains(book.Author)
select book.Id;
Assert.Throws(typeof(NotSupportedException), () => query.ToString());
}
}
[Fact]
public static void EnumerableContains_with_parameter_and_store_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE ([Extent1].[Title] IN (N'Title1', N'Title2'))
OR ([Extent1].[Title] = @p__linq__0)
OR ([Extent1].[Title] IS NULL)
/*
String p__linq__0 = ""Title3""
*/";
var parameter = "Title3";
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = from book in context.Books
where new[] { "Title1", "Title2", parameter, null }.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void EnumerableContains_with_parameter_and_csharp_null_is_translated_to_expected_sql()
{
const string expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Books] AS [Extent1]
WHERE (([Extent1].[Title] IN (N'Title1', N'Title2')) AND ([Extent1].[Title] IS NOT NULL))
OR (([Extent1].[Title] = @p__linq__0) AND (NOT ([Extent1].[Title] IS NULL OR @p__linq__0 IS NULL)))
OR (([Extent1].[Title] IS NULL) AND (@p__linq__0 IS NULL))
OR ([Extent1].[Title] IS NULL)
/*
String p__linq__0 = ""Title3""
*/";
var parameter = "Title3";
using (var context = new UnicodeContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = from book in context.Books
where new[] { "Title1", "Title2", parameter, null }.Contains(book.Title)
select book.Id;
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
[Fact]
public static void Contains_throws_for_constant_null_array()
{
using (var context = new UnicodeContext())
{
string[] names = null;
var query = context.Books.Where(b => names.Contains(b.Title));
Assert.Throws<NotSupportedException>(() => query.ToString());
}
}
[Fact]
public static void Contains_throws_for_constant_null_list()
{
using (var context = new UnicodeContext())
{
List<string> names = null;
var query = context.Books.Where(b => names.Contains(b.Title));
Assert.Throws<NotSupportedException>(() => query.ToString());
}
}
[Fact]
public static void Contains_on_non_static_collection_of_enums()
{
const string expectedSql =
@"SELECT
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Books] AS [Extent2]
WHERE 0 = [Extent2].[Genre]
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Books] AS [Extent3]
WHERE 0 = [Extent3].[Genre]
)) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[Books] AS [Extent1]";
using (var context = new UnicodeContext())
{
var query = context.Books.Select(q => context.Books.Select(b => b.Genre).Contains(Genre.Action));
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
}
}
}
}

View File

@@ -0,0 +1,202 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Data.Entity.TestModels.ArubaModel;
using System.Linq;
using Xunit;
public class DefaultIfEmptyTests : FunctionalTestBase
{
[Fact]
public void SelectMany_with_DefaultIfEmpty_translates_into_left_outer_join()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Number] AS [Number],
[Extent2].[Comment] AS [Comment],
[Extent2].[Resolution] AS [Resolution],
[Extent2].[Failure_Id] AS [Failure_Id],
[Extent2].[ArubaOwner_Id] AS [ArubaOwner_Id]
FROM [dbo].[ArubaOwners] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ArubaOwner_Id]";
var query = context.Owners.SelectMany(c => c.Bugs.DefaultIfEmpty());
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that owners that have empty collecion of bugs are projected as nulls
var results = query.ToList();
var ownersWithoutBugsCount = context.Owners.Count(o => !o.Bugs.Any());
Assert.Equal(ownersWithoutBugsCount, results.Count(r => r == null));
}
}
[Fact]
public void DefaultIfEmpty_with_null_default()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Alias] AS [Alias],
[Extent2].[Id] AS [Id1],
[Extent2].[Number] AS [Number],
[Extent2].[Comment] AS [Comment],
[Extent2].[Resolution] AS [Resolution],
[Extent2].[Failure_Id] AS [Failure_Id],
[Extent2].[ArubaOwner_Id] AS [ArubaOwner_Id]
FROM [dbo].[ArubaOwners] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[ArubaOwner_Id]) AND (1 = [Extent2].[Id])";
var query = context.Owners.SelectMany(c => c.Bugs.Where(b => b.Id == 1).DefaultIfEmpty(), (o, b) => new { o, b });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that all owners are projected
// verify that the only bug that is non-null has Id = 1
var results = query.ToList();
var ownersCount = context.Owners.Count();
Assert.Equal(ownersCount, results.Select(r => r.o.Id).Distinct().Count());
for (int i = 0; i < ownersCount; i++)
{
var bug = results[i].b;
Assert.True(bug == null || bug.Id == 1);
}
}
}
[Fact]
public void DefaultIfEmpty_with_non_null_default()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Alias] AS [Alias],
CASE WHEN (CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS tinyint) ELSE cast(1 as tinyint) END IS NULL) THEN 0 ELSE [Extent2].[Id] END AS [C1]
FROM [dbo].[ArubaOwners] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[ArubaOwner_Id]) AND (1 = [Extent2].[Id])";
var query = context.Owners.SelectMany(c => c.Bugs.Where(b => b.Id == 1).Select(b => b.Id).DefaultIfEmpty(), (o, b) => new { o, b });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that all owners are projected
// verify that the only bug that is non 0 has Id = 1
var results = query.ToList();
var ownersCount = context.Owners.Count();
Assert.Equal(ownersCount, results.Select(r => r.o.Id).Distinct().Count());
for (int i = 0; i < ownersCount; i++)
{
var bugId = results[i].b;
Assert.True(bugId == 0 || bugId == 1);
}
}
}
[Fact]
public void DefaultIfEmpty_with_explicit_default()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Alias] AS [Alias],
CASE WHEN (CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS tinyint) ELSE cast(1 as tinyint) END IS NULL) THEN N'Foo' ELSE [Extent2].[Comment] END AS [C1]
FROM [dbo].[ArubaOwners] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[ArubaOwner_Id]) AND (1 = [Extent2].[Id])";
var query = context.Owners.SelectMany(o => o.Bugs.Where(b => b.Id == 1).Select(b => b.Comment).DefaultIfEmpty("Foo"), (o, b) => new { o, b });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that all owners are projected
// verify that the only bug that is non "Foo" has Id = 1
var results = query.ToList();
var bugCommentForIdOne = context.Bugs.Where(b => b.Id == 1).Single().Comment;
var ownersCount = context.Owners.Count();
Assert.Equal(ownersCount, results.Select(r => r.o.Id).Distinct().Count());
for (int i = 0; i < ownersCount; i++)
{
var bugComment = results[i].b;
Assert.True(bugComment == "Foo" || bugComment == bugCommentForIdOne);
}
}
}
[Fact]
public void DefaultIfEmpty_with_anonymous_type_default()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Alias] AS [Alias],
CASE WHEN (CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS tinyint) ELSE cast(1 as tinyint) END IS NULL) THEN -1 ELSE [Extent2].[Id] END AS [C1],
CASE WHEN (CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS tinyint) ELSE cast(1 as tinyint) END IS NULL) THEN N'Unknown' ELSE [Extent2].[Comment] END AS [C2],
CASE WHEN (CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS tinyint) ELSE cast(1 as tinyint) END IS NULL) THEN 3 ELSE [Extent2].[Resolution] END AS [C3]
FROM [dbo].[ArubaOwners] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[ArubaOwner_Id]) AND (5 = [Extent2].[Id])";
var query = context.Owners.SelectMany(o => o.Bugs.Where(b => b.Id == 5).Select(b => new { b.Id, b.Comment, b.Resolution }).DefaultIfEmpty(new { Id = -1, Comment = "Unknown", Resolution = (ArubaBugResolution?)ArubaBugResolution.NoRepro }), (o, b) => new { o, b });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that all owners are projected
// verify that the only bug that is non default has Id = 5
var results = query.ToList();
var bugCommentForIdFive = context.Bugs.Where(b => b.Id == 5).Single().Comment;
var bugResolutionForIdFive = context.Bugs.Where(b => b.Id == 5).Single().Resolution;
var ownersCount = context.Owners.Count();
Assert.Equal(ownersCount, results.Select(r => r.o.Id).Distinct().Count());
for (int i = 0; i < ownersCount; i++)
{
var bug = results[i].b;
Assert.True(bug.Id == -1 || bug.Id == 5);
Assert.True(bug.Comment == "Unknown" || bug.Comment == bugCommentForIdFive);
Assert.True(bug.Resolution == ArubaBugResolution.NoRepro || bug.Resolution == bugResolutionForIdFive);
}
}
}
[Fact]
public void SelectMany_of_two_entity_sets_withDefaultIfEmpty_translated_to_left_outer_join()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Number] AS [Number],
[Extent2].[Comment] AS [Comment],
[Extent2].[Resolution] AS [Resolution],
[Extent2].[Failure_Id] AS [Failure_Id],
[Extent2].[ArubaOwner_Id] AS [ArubaOwner_Id]
FROM [dbo].[ArubaFailures] AS [Extent1]
LEFT OUTER JOIN [dbo].[ArubaBugs] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Failure_Id]
WHERE [Extent1].[Discriminator] IN (N'ArubaBaseline',N'ArubaTestFailure',N'ArubaFailure')";
var query = context.Failures.GroupJoin(context.Bugs, f => f.Id, b => b.Failure.Id, (f, b) => new { f, b }).SelectMany(r => r.b.DefaultIfEmpty());
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that failures that have empty collecion of bugs are projected as nulls
var results = query.ToList();
var failuresWithoutBugsCount = context.Failures.Count(o => !o.Bugs.Any());
Assert.Equal(failuresWithoutBugsCount, results.Count(r => r == null));
}
}
}
}

View File

@@ -0,0 +1,179 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Data.Entity.TestModels.ArubaModel;
using System.Collections.Generic;
using System.Linq;
using Xunit;
public class FuncletizationTests : FunctionalTestBase
{
[Fact]
public void Funcletize_ICollection_count_when_passed_as_parameter()
{
var localList = new List<int> { 1, 2, 3 };
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
@p__linq__0 AS [C1]
FROM [dbo].[ArubaTasks] AS [Extent1]
/*
Int32 p__linq__0 = 3
*/";
var query = context.Tasks.Select(t => localList.Count);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that correct value gets projected
var results = query.ToList();
Assert.True(results.All(r => r == 3));
}
}
[Fact]
public void Funcletize_byte_array()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[ArubaTasks] AS [Extent1]
WHERE 0x010203 = 0x010203";
var query = context.Tasks.Where(c => new byte[] { 1, 2, 3 } == new byte[] { 1, 2, 3 }).Select(c => c.Id);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
// verify that filter is a no-op
var results = query.ToList();
var expectedCount = context.Tasks.Count();
Assert.Equal(expectedCount, results.Count);
}
}
[Fact]
public void Funcletize_decimal_constructors()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
1 AS [C1],
1.5 AS [C2],
2.5 AS [C3],
cast(5 as decimal(18)) AS [C4],
cast(7 as decimal(18)) AS [C5],
cast(9 as decimal(18)) AS [C6],
cast(11 as decimal(18)) AS [C7],
0.0013 AS [C8]
FROM [dbo].[ArubaTasks] AS [Extent1]";
var query = context.Tasks.Select(c => new
{
a = new Decimal(1.5),
b = new Decimal((float)2.5),
c = new Decimal(5),
e = new Decimal((long)7),
f = new Decimal((uint)9),
g = new Decimal((ulong)11),
h = new Decimal(13, 0, 0, false, 4),
});
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
foreach (var result in results)
{
Assert.Equal((decimal)1.5, result.a);
Assert.Equal((decimal)2.5, result.b);
Assert.Equal(5, result.c);
Assert.Equal(7, result.e);
Assert.Equal(9, result.f);
Assert.Equal(11, result.g);
Assert.Equal((decimal)0.0013, result.h);
}
}
}
[Fact]
public void Funcletize_string_constructors()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
1 AS [C1],
N'aaaaa' AS [C2]
FROM [dbo].[ArubaTasks] AS [Extent1]";
var query = context.Tasks.Select(c => new
{
b = new String('a', 5),
});
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var result = query.ToList();
Assert.True(result.All(r => r.b == "aaaaa"));
}
}
[Fact]
public void Funcletize_static_field()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
@p__linq__0 AS [C1]
FROM [dbo].[ArubaTasks] AS [Extent1]
/*
String p__linq__0 = ""staticField""
*/";
var query = context.Tasks.Select(c => StubClass.StaticField);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var result = query.ToList();
Assert.True(result.All(r => r == "staticField"));
}
}
[Fact]
public void Funcletize_static_property()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
@p__linq__0 AS [C1]
FROM [dbo].[ArubaTasks] AS [Extent1]
/*
String p__linq__0 = ""StaticProperty""
*/";
var query = context.Tasks.Select(c => StubClass.StaticProperty);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var result = query.ToList();
Assert.True(result.All(r => r == "StaticProperty"));
}
}
public static class StubClass
{
public static string StaticField = "staticField";
public static string StaticProperty { get; set; }
static StubClass()
{
StaticProperty = "StaticProperty";
}
}
}
}

View File

@@ -0,0 +1,299 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Data.Entity.TestModels.ArubaModel;
using System.Linq;
using Xunit;
public class GroupByOptimizationTests : FunctionalTestBase
{
[Fact]
public void GroupBy_is_optimized_when_projecting_group_key()
{
var expectedSql =
@"SELECT
[Distinct1].[FirstName] AS [FirstName]
FROM ( SELECT DISTINCT
[Extent1].[FirstName] AS [FirstName]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Distinct1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => g.Key);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => g.Key).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_group_count()
{
var expectedSql =
@"SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
COUNT(1) AS [A1]
FROM [dbo].[ArubaOwners] AS [Extent1]
GROUP BY [Extent1].[FirstName]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => g.Count());
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => g.Count()).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_expression_containing_group_key()
{
var expectedSql =
@"SELECT
[Extent1].[Id] * 2 AS [C1]
FROM [dbo].[ArubaOwners] AS [Extent1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.Id).Select(g => g.Key * 2);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.Id).Select(g => g.Key * 2).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_aggregate_on_the_group()
{
var expectedSql =
@"SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
MAX([Extent1].[Id]) AS [A1]
FROM [dbo].[ArubaOwners] AS [Extent1]
GROUP BY [Extent1].[FirstName]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => g.Max(p => p.Id));
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => g.Max(p => p.Id)).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_anonymous_type_containing_group_key_and_group_aggregate()
{
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [FirstName],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
MAX([Extent1].[Id]) AS [A1]
FROM [dbo].[ArubaOwners] AS [Extent1]
GROUP BY [Extent1].[FirstName]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => new { Key = g.Key, Aggregate = g.Max(p => p.Id) });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => new { Key = g.Key, Aggregate = g.Max(p => p.Id) }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Key == i.Key && o.Aggregate == i.Aggregate);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_anonymous_type_containing_group_key_and_multiple_group_aggregates()
{
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [FirstName],
[GroupBy1].[A1] AS [C2],
[GroupBy1].[A2] AS [C3]
FROM ( SELECT
[Extent1].[K1] AS [K1],
MAX([Extent1].[A1]) AS [A1],
MIN([Extent1].[A2]) AS [A2]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
[Extent1].[Id] AS [A1],
[Extent1].[Id] + 2 AS [A2]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Extent1]
GROUP BY [K1]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => new { key1 = g.Key, key2 = g.Key, max = g.Max(p => p.Id), min = g.Min(s => s.Id + 2) });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => new { key1 = g.Key, key2 = g.Key, max = g.Max(p => p.Id), min = g.Min(s => s.Id + 2) }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.key1 == i.key1 && o.key2 == i.key2 && o.max == i.max && o.min == i.min);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_conditional_expression_containing_group_key()
{
var expectedSql =
@"SELECT
1 AS [C1],
CASE WHEN ([Distinct1].[FirstName] IS NULL) THEN N'is null' ELSE N'not null' END AS [C2],
CASE WHEN (((@p__linq__0 = 1) AND (@p__linq__1 = 1)) OR ((@p__linq__2 = 1) AND (@p__linq__3 = 1))) THEN cast(1 as bit) WHEN ( NOT (((@p__linq__0 = 1) AND (@p__linq__1 = 1)) OR ((@p__linq__2 = 1) AND (@p__linq__3 = 1)))) THEN cast(0 as bit) END AS [C3]
FROM ( SELECT DISTINCT
[Extent1].[FirstName] AS [FirstName]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Distinct1]
/*
Boolean p__linq__0 = True
Boolean p__linq__1 = False
Boolean p__linq__2 = False
Boolean p__linq__3 = True
*/";
bool a = true;
bool b = false;
bool c = true;
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => new { keyIsNull = g.Key == null ? "is null" : "not null", logicExpression = (a && b || b && c) });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => new { keyIsNull = g.Key == null ? "is null" : "not null", logicExpression = (a && b || b && c) }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.keyIsNull == i.keyIsNull && o.logicExpression == i.logicExpression);
}
}
[Fact]
public void GroupBy_is_optimized_when_filerting_and_projecting_anonymous_type_with_group_key_and_function_aggregate()
{
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[K1] AS [FirstName],
[GroupBy1].[A1] AS [C2]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
AVG( CAST( [Extent1].[Id] AS float)) AS [A1]
FROM [dbo].[ArubaOwners] AS [Extent1]
WHERE [Extent1].[Id] > 5
GROUP BY [Extent1].[FirstName]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.Where(o => o.Id > 5).GroupBy(o => o.FirstName).Select(g => new { FirstName = g.Key, AverageId = g.Average(p => p.Id) });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList().OrderBy(r => r.AverageId).ToList();
var expected = context.Owners.ToList().Where(o => o.Id > 5).GroupBy(o => o.FirstName).Select(g => new { FirstName = g.Key, AverageId = g.Average(p => p.Id) }).OrderBy(r => r.AverageId).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.FirstName == i.FirstName && o.AverageId == i.AverageId);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_function_aggregate_with_expression()
{
var expectedSql =
@"SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
[Extent1].[K1] AS [K1],
MAX([Extent1].[A1]) AS [A1]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
[Extent1].[Id] * 2 AS [A1]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Extent1]
GROUP BY [K1]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(p => p.FirstName).Select(g => g.Max(p => p.Id * 2));
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(p => p.FirstName).Select(g => g.Max(p => p.Id * 2)).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
[Fact]
public void GroupBy_is_optimized_when_projecting_expression_with_multiple_function_aggregates()
{
var expectedSql =
@"SELECT
1 AS [C1],
[GroupBy1].[A1] - [GroupBy1].[A2] AS [C2]
FROM ( SELECT
[Extent1].[FirstName] AS [K1],
MAX([Extent1].[Id]) AS [A1],
MIN([Extent1].[Id]) AS [A2]
FROM [dbo].[ArubaOwners] AS [Extent1]
GROUP BY [Extent1].[FirstName]
) AS [GroupBy1]";
using (var context = new ArubaContext())
{
var query = context.Owners.GroupBy(o => o.FirstName).Select(g => new { maxMinusMin = g.Max(p => p.Id) - g.Min(s => s.Id) });
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().GroupBy(o => o.FirstName).Select(g => new { maxMinusMin = g.Max(p => p.Id) - g.Min(s => s.Id) }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.maxMinusMin == i.maxMinusMin);
}
}
[Fact]
public void GroupBy_is_optimized_when_grouping_by_row_and_projecting_column_of_the_key_row()
{
var expectedSql =
@"SELECT
[Distinct1].[FirstName] AS [FirstName]
FROM ( SELECT DISTINCT
[Extent1].[FirstName] AS [FirstName]
FROM [dbo].[ArubaOwners] AS [Extent1]
WHERE [Extent1].[Id] < 4
) AS [Distinct1]";
using (var context = new ArubaContext())
{
var query = context.Owners.Where(o => o.Id < 4).GroupBy(g => new { g.FirstName }).Select(g => g.Key.FirstName);
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Owners.ToList().Where(o => o.Id < 4).GroupBy(g => new { g.FirstName }).Select(g => g.Key.FirstName).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o == i);
}
}
}
}

View File

@@ -0,0 +1,262 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Data.Entity.Infrastructure;
using System.Data.Entity.TestModels.ArubaModel;
using System.Linq;
using Xunit;
public class IncludeTests : FunctionalTestBase
{
[Fact]
public void Include_on_one_to_many_relationship()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Runs.Include(c => c.Tasks);
var results = query.ToList();
var tasksForRuns = context.Runs.Select(r => r.Tasks).ToList();
for (var i = 0; i < results.Count; i++)
{
Assert.Equal(tasksForRuns[i].Count, results[i].Tasks.Count);
var expectedTasks = tasksForRuns[i].Select(t => t.Id).ToList();
var actualTasks = results[i].Tasks.Select(t => t.Id).ToList();
Assert.True(Enumerable.SequenceEqual(expectedTasks, actualTasks));
}
}
}
[Fact]
public void Include_on_many_to_many_relationship()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Configs.Include(c => c.Failures);
var results = query.ToList();
var failuresForConfigs = context.Configs.Select(r => r.Failures).ToList();
for (var i = 0; i < results.Count; i++)
{
Assert.Equal(failuresForConfigs[i].Count, results[i].Failures.Count);
var expectedFailures = failuresForConfigs[i].Select(t => t.Id).ToList();
var actualFailures = results[i].Failures.Select(t => t.Id).ToList();
Assert.True(Enumerable.SequenceEqual(expectedFailures, actualFailures));
}
}
}
[Fact]
public void Include_one_to_one_relationship()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Owners.Include(o => o.OwnedRun);
var results = query.ToList();
var runsForOwners = context.Owners.Select(r => r.OwnedRun).ToList();
Enumerable.SequenceEqual(runsForOwners, results.Select(r => r.OwnedRun));
}
}
[Fact]
public void Multiple_includes()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Failures.Include(f => f.Configs).Include(f => f.Bugs);
var results = query.ToList();
var configsForFailures = context.Failures.Select(r => r.Configs).ToList();
var bugsForFailures = context.Failures.Select(r => r.Bugs).ToList();
for (var i = 0; i < results.Count; i++)
{
Assert.Equal(bugsForFailures[i].Count, results[i].Bugs.Count);
Assert.Equal(configsForFailures[i].Count, results[i].Configs.Count);
var expectedBugs = bugsForFailures[i].Select(b => b.Id).ToList();
var expectedConfigs = configsForFailures[i].Select(c => c.Id).ToList();
var actualBugs = results[i].Bugs.Select(b => b.Id).ToList();
var actualConfigs = results[i].Configs.Select(c => c.Id).ToList();
Enumerable.SequenceEqual(expectedBugs, actualBugs);
Enumerable.SequenceEqual(expectedConfigs, actualConfigs);
}
}
}
[Fact]
public void Include_with_string_overload()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Runs.Include("Tasks");
var results = query.ToList();
var tasksForRuns = context.Runs.Select(r => r.Tasks).ToList();
for (var i = 0; i < results.Count; i++)
{
Assert.Equal(tasksForRuns[i].Count, results[i].Tasks.Count);
var expectedTasks = tasksForRuns[i].Select(t => t.Id).ToList();
var actualTasks = results[i].Tasks.Select(t => t.Id).ToList();
Enumerable.SequenceEqual(expectedTasks, actualTasks);
}
}
}
[Fact]
public void Nested_include()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Owners.Include("OwnedRun.Tasks");
var results = query.ToList();
var tasksForOwners = context.Owners.Select(o => o.OwnedRun.Tasks).ToList();
for (var i = 0; i < results.Count; i++)
{
Assert.Equal(tasksForOwners[i].Count, results[i].OwnedRun.Tasks.Count);
var expectedTasks = tasksForOwners[i].Select(t => t.Id).ToList();
var actualTasks = results[i].OwnedRun.Tasks.Select(t => t.Id).ToList();
Enumerable.SequenceEqual(expectedTasks, actualTasks);
}
}
}
[Fact]
public void Include_propagation_over_filter()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Owners.Include(o => o.OwnedRun).Where(o => o.Id == 1);
var results = query.ToList();
Assert.NotNull(results.First().OwnedRun);
}
}
[Fact]
public void Include_propagation_over_sort()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Owners.Include(o => o.OwnedRun).OrderBy(o => o.Id == 1);
var results = query.ToList();
Assert.NotNull(results.First().OwnedRun);
}
}
[Fact]
public void Include_propagation_over_type_filter()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Configs.Include(o => o.Failures).OfType<ArubaMachineConfig>();
var results = query.ToList();
Assert.True(results.Any(r => r.Failures.Count > 0));
}
}
[Fact]
public void Include_propagation_over_first()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var results = context.Configs.Include(o => o.Failures).First();
Assert.NotNull(results.Failures);
Assert.True(results.Failures.Count > 0);
}
}
[Fact]
public void Include_propagation_over_first_with_predicate()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var results = context.Configs.Include(o => o.Failures).First(o => o.Id > 0);
Assert.NotNull(results.Failures);
Assert.True(results.Failures.Count > 0);
}
}
[Fact]
public void Include_propagation_over_first_or_default()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var results = context.Configs.Include(o => o.Failures).FirstOrDefault();
Assert.NotNull(results.Failures);
Assert.True(results.Failures.Count > 0);
}
}
[Fact]
public void Include_propagation_over_first_or_default_with_predicate()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var results = context.Configs.Include(o => o.Failures).FirstOrDefault(o => o.Id > 0);
Assert.NotNull(results.Failures);
Assert.True(results.Failures.Count > 0);
}
}
[Fact]
public void Include_from_concat_combined()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Failures.Include(f => f.Bugs).Concat(context.Failures.Include(f => f.Configs));
var results = query.ToList();
Assert.True(results.Any(r => r.Bugs.Count > 0));
Assert.True(results.Any(r => r.Configs.Count > 0));
}
}
[Fact]
public void Include_from_except_takes_span_information_from_first_collection_ignores_from_second()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Failures.Include(f => f.Bugs).Except(context.Failures.Where(f => f.Id == 1).Include(f => f.Configs));
var results = query.ToList();
Assert.True(results.Any(r => r.Bugs.Count > 0));
Assert.True(results.All(r => r.Configs == null));
}
}
[Fact]
public void Include_from_intersect_combined()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Failures.Include(f => f.Bugs).Intersect(context.Failures.Include(f => f.Configs));
var results = query.ToList();
Assert.True(results.Any(r => r.Bugs.Count > 0));
Assert.True(results.Any(r => r.Configs.Count > 0));
}
}
[Fact]
public void Include_from_union_combined()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var query = context.Failures.Include(f => f.Bugs).Union(context.Failures.Include(f => f.Configs));
var results = query.ToList();
Assert.True(results.Any(r => r.Bugs.Count > 0));
Assert.True(results.Any(r => r.Configs.Count > 0));
}
}
}
}

View File

@@ -0,0 +1,195 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.TestModels.ArubaModel;
using System.Linq;
using System.Reflection;
using Xunit;
public class MaterializationTests : FunctionalTestBase
{
[Fact]
public void Can_materialize_list_of_entity_properties()
{
using (var context = new ArubaContext())
{
var query = context.Runs.Where(r => r.Id == 1).Select(r => new List<int> { r.Id, r.RunOwner.Id });
// materializing results
var results = query.ToList();
var runId = context.Runs.Select(r => r.Id).First(r => r == 1);
var ownerId = context.Runs.Select(r => r.RunOwner.Id).First(r => r == 1);
Assert.Equal(1, results.Count);
Assert.Equal(2, results[0].Count);
Assert.Equal(runId, results[0][0]);
Assert.Equal(ownerId, results[0][1]);
}
}
[Fact]
public void Materialize_array_of_entity_properties_throws()
{
using (var context = new ArubaContext())
{
var query = context.Runs.Where(r => r.Id == 1).Select(r => new int[] { r.Id, r.RunOwner.Id });
var innerException = Assert.Throws<TargetInvocationException>(() => query.ToList())
.InnerException;
Assert.IsType<InvalidOperationException>(innerException);
innerException.ValidateMessage(
typeof(DbContext).Assembly,
"ObjectQuery_UnableToMaterializeArray",
null,
"System.Int32[]",
"System.Collections.Generic.List`1[System.Int32]");
}
}
[Fact]
public void Materializing_empty_list_throws()
{
using (var context = new ArubaContext())
{
var query = context.Runs.Select(r => new List<int> { });
Assert.Throws<NotSupportedException>(() => query.ToList()).
ValidateMessage(
typeof(DbContext).Assembly,
"ELinq_UnsupportedEnumerableType",
null,
"System.Collections.Generic.List`1");
}
}
[Fact]
public void Can_materialize_list_inside_anonymous_type()
{
using (var context = new ArubaContext())
{
var query = context.Runs.Where(r => r.Id == 1).Select(r => new { r.Id, List = new List<string> { r.Name, "a", "b" } });
var results = query.ToList();
var runId = context.Runs.Select(r => r.Id).First(r => r == 1);
var runName = context.Runs.Where(r => r.Id == 1).Select(r => r.Name).First();
Assert.Equal(1, results.Count);
Assert.Equal(runId, results[0].Id);
Assert.Equal(3, results[0].List.Count);
Assert.Equal(runName, results[0].List[0]);
Assert.Equal("a", results[0].List[1]);
Assert.Equal("b", results[0].List[2]);
}
}
[Fact]
public void Can_materialize_collection()
{
using (var context = new ArubaContext())
{
var query = context.Failures.Where(f => f.Id == 1).Select(f => f.Bugs);
var results = query.ToList();
var bugs = context.Bugs.Where(b => b.Failure.Id == 1).ToList();
Assert.Equal(1, results.Count);
Assert.Equal(bugs.Count, results[0].Count);
}
}
[Fact]
public void Can_materialize_collection_inside_anonymous_type()
{
using (var context = new ArubaContext())
{
var query = context.Failures.Where(f => f.Id == 1).Select(f => new { f.Bugs });
var results = query.ToList();
var bugs = context.Bugs.Where(b => b.Failure.Id == 1).ToList();
Assert.Equal(1, results.Count);
Assert.Equal(bugs.Count, results[0].Bugs.Count);
}
}
[Fact]
public void Can_materialize_properties_into_non_mapped_type()
{
using (var context = new ArubaContext())
{
var query = context.Owners.Where(o => o.Id == 1).Select(o => new MyNonMappedType { Id = o.Id, Name = o.FirstName });
var results = query.ToList();
var id = context.Owners.Select(o => o.Id).First(r => r == 1);
var name = context.Owners.Where(o => o.Id == 1).Select(o => o.FirstName).First();
Assert.Equal(1, results.Count);
Assert.Equal(id, results[0].Id);
Assert.Equal(name, results[0].Name);
}
}
[Fact]
public void Can_materialize_nested_anonymous_types()
{
using (var context = new ArubaContext())
{
var query = context.Owners.Where(o => o.Id == 1).Select(o => new
{
o.Id,
Name = new { First = o.FirstName, Last = o.LastName }
});
var results = query.ToList();
var id = context.Owners.Select(o => o.Id).First(r => r == 1);
var firstName = context.Owners.Where(o => o.Id == 1).Select(o => o.FirstName).First();
var lastName = context.Owners.Where(o => o.Id == 1).Select(o => o.LastName).First();
Assert.Equal(1, results.Count);
Assert.Equal(id, results[0].Id);
Assert.Equal(firstName, results[0].Name.First);
Assert.Equal(lastName, results[0].Name.Last);
}
}
[Fact]
public void Can_materialize_null_complex_type()
{
using (var context = new ArubaContext())
{
var query = context.Runs.Select(r => r.Tasks.Where(t => t.Id < 0).Select(t => t.TaskInfo).FirstOrDefault());
var results = query.ToList();
Assert.IsType<List<ArubaTaskInfo>>(results);
foreach (var result in results)
{
Assert.Null(result);
}
}
}
[Fact]
public void Materialize_DbSet_throws()
{
using (var context = new ArubaContext())
{
Assert.Throws<ArgumentException>(() => context.Runs.Select(r => context.Owners));
context.Runs.Select(r => context.Owners.AsEnumerable()).ToList();
}
}
[Fact]
public void Materialize_ObjectQuery_throws()
{
using(var context = new ArubaContext())
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var owners = objectContext.CreateQuery<ArubaOwner>("Owners");
Assert.Throws<InvalidOperationException>(() => context.Runs.Select(r => owners).ToList());
context.Runs.Select(r => owners.AsEnumerable()).ToList();
}
}
public class MyNonMappedType
{
public int Id { get; set; }
public string Name { get; set; }
}
}
}

View File

@@ -0,0 +1,390 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query.LinqToEntities
{
using System.Data.Entity.TestModels.ArubaModel;
using SimpleModel;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using Xunit;
public class OrderByLiftingTests : FunctionalTestBase
{
[Fact]
public void OrderBy_ThenBy_lifted_above_projection()
{
using (var context = new ArubaContext())
{
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 });
var baseline = context.Owners.Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_lifted_above_filter_with_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_lifted_above_filter_without_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_lifted_above_type_filter()
{
using (var context = new ArubaContext())
{
var query = context.Configs.OrderByDescending(p => p.Arch).ThenBy(p => p.Id).OfType<ArubaMachineConfig>();
var baseline = context.Configs.OfType<ArubaMachineConfig>().OrderByDescending(p => p.Arch).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Configs.ToList().OrderByDescending(p => p.Arch).ThenBy(p => p.Id).OfType<ArubaMachineConfig>().ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_lifted_above_projection()
{
using (var context = new ArubaContext())
{
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 });
var baseline = context.Owners.Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_lifted_above_filter_with_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var expectedSq =
@"SELECT
[Skip1].[Id] AS [Id],
[Skip1].[FirstName] AS [FirstName],
[Skip1].[LastName] AS [LastName],
[Skip1].[Alias] AS [Alias]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Alias] AS [Alias]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Alias] AS [Alias], row_number() OVER (ORDER BY [Extent1].[FirstName] DESC, [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 5
) AS [Skip1]
WHERE (0 = ([Skip1].[Id] % 2)) AND ([Skip1].[Id] % 2 IS NOT NULL)
ORDER BY [Skip1].[FirstName] DESC, [Skip1].[Id] ASC";
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Where(p => p.Id % 2 == 0);
QueryTestHelpers.VerifyDbQuery(query, expectedSq);
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_lifted_above_filter_without_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var expectedSq =
@"SELECT
[Skip1].[Id] AS [Id],
[Skip1].[FirstName] AS [FirstName],
[Skip1].[LastName] AS [LastName],
[Skip1].[Alias] AS [Alias]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Alias] AS [Alias]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Alias] AS [Alias], row_number() OVER (ORDER BY [Extent1].[FirstName] DESC, [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[ArubaOwners] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 5
) AS [Skip1]
WHERE 0 = ([Skip1].[Id] % 2)
ORDER BY [Skip1].[FirstName] DESC, [Skip1].[Id] ASC";
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Where(p => p.Id % 2 == 0);
QueryTestHelpers.VerifyDbQuery(query, expectedSq);
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_lifted_above_type_filter()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Project1].[C1] AS [C1],
[Project1].[C2] AS [C2],
[Project1].[C3] AS [C3],
[Project1].[C4] AS [C4],
[Project1].[C5] AS [C5],
[Project1].[C6] AS [C6],
[Project1].[C7] AS [C7],
[Project1].[C8] AS [C8]
FROM ( SELECT
[Skip1].[Id] AS [Id],
[Skip1].[Arch] AS [Arch],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Discriminator] END AS [C1],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Id] END AS [C2],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[OS] END AS [C3],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Lang] END AS [C4],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Arch] END AS [C5],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Host] END AS [C6],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Address] END AS [C7],
CASE WHEN ([Skip1].[Discriminator] = N'ArubaMachineConfig') THEN [Skip1].[Location] END AS [C8]
FROM ( SELECT [Filter1].[Id] AS [Id], [Filter1].[OS] AS [OS], [Filter1].[Lang] AS [Lang], [Filter1].[Arch] AS [Arch], [Filter1].[Host] AS [Host], [Filter1].[Address] AS [Address], [Filter1].[Location] AS [Location], [Filter1].[Discriminator] AS [Discriminator]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[OS] AS [OS], [Extent1].[Lang] AS [Lang], [Extent1].[Arch] AS [Arch], [Extent1].[Host] AS [Host], [Extent1].[Address] AS [Address], [Extent1].[Location] AS [Location], [Extent1].[Discriminator] AS [Discriminator], row_number() OVER (ORDER BY [Extent1].[Arch] DESC, [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[ArubaConfigs] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'ArubaMachineConfig',N'ArubaConfig')
) AS [Filter1]
WHERE [Filter1].[row_number] > 5
) AS [Skip1]
WHERE [Skip1].[Discriminator] = N'ArubaMachineConfig'
) AS [Project1]
ORDER BY [Project1].[Arch] DESC, [Project1].[Id] ASC";
var query = context.Configs.OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Skip(5).OfType<ArubaMachineConfig>();
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Configs.ToList().OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Skip(5).OfType<ArubaMachineConfig>().ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Take_lifted_above_projection()
{
using (var context = new ArubaContext())
{
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 });
var baseline = context.Owners.Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Take_lifted_above_filter_with_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Take_lifted_above_filter_without_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Take(10).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Take_lifted_above_type_filter()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Project1].[C1] AS [C1],
[Project1].[C2] AS [C2],
[Project1].[C3] AS [C3],
[Project1].[C4] AS [C4],
[Project1].[C5] AS [C5],
[Project1].[C6] AS [C6],
[Project1].[C7] AS [C7],
[Project1].[C8] AS [C8]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Arch] AS [Arch],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Discriminator] END AS [C1],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Id] END AS [C2],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[OS] END AS [C3],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Lang] END AS [C4],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Arch] END AS [C5],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Host] END AS [C6],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Address] END AS [C7],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Location] END AS [C8]
FROM ( SELECT TOP (10) [Extent1].[Id] AS [Id], [Extent1].[OS] AS [OS], [Extent1].[Lang] AS [Lang], [Extent1].[Arch] AS [Arch], [Extent1].[Host] AS [Host], [Extent1].[Address] AS [Address], [Extent1].[Location] AS [Location], [Extent1].[Discriminator] AS [Discriminator]
FROM [dbo].[ArubaConfigs] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'ArubaMachineConfig',N'ArubaConfig')
ORDER BY [Extent1].[Arch] DESC, [Extent1].[Id] ASC
) AS [Limit1]
WHERE [Limit1].[Discriminator] = N'ArubaMachineConfig'
) AS [Project1]
ORDER BY [Project1].[Arch] DESC, [Project1].[Id] ASC";
var query = context.Configs.OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Take(10).OfType<ArubaMachineConfig>();
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Configs.ToList().OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Take(10).OfType<ArubaMachineConfig>().ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_Take_lifted_above_projection()
{
using (var context = new ArubaContext())
{
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 });
var baseline = context.Owners.Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Select(p => new { p.FirstName, p.Id, Foo = p.Id * 5 }).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_Take_lifted_above_filter_with_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_Take_lifted_above_filter_without_clr_null_semantics()
{
using (var context = new ArubaContext())
{
((IObjectContextAdapter)context).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = false;
var query = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0);
var baseline = context.Owners.OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0).OrderByDescending(p => p.FirstName).ThenBy(p => p.Id);
Assert.Equal(baseline.ToString(), query.ToString());
var results = query.ToList();
var expected = context.Owners.ToList().OrderByDescending(p => p.FirstName).ThenBy(p => p.Id).Skip(5).Take(10).Where(p => p.Id % 2 == 0).ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
[Fact]
public void OrderBy_ThenBy_Skip_Take_lifted_above_type_filter()
{
using (var context = new ArubaContext())
{
var expectedSql =
@"SELECT
[Project1].[C1] AS [C1],
[Project1].[C2] AS [C2],
[Project1].[C3] AS [C3],
[Project1].[C4] AS [C4],
[Project1].[C5] AS [C5],
[Project1].[C6] AS [C6],
[Project1].[C7] AS [C7],
[Project1].[C8] AS [C8]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Arch] AS [Arch],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Discriminator] END AS [C1],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Id] END AS [C2],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[OS] END AS [C3],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Lang] END AS [C4],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Arch] END AS [C5],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Host] END AS [C6],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Address] END AS [C7],
CASE WHEN ([Limit1].[Discriminator] = N'ArubaMachineConfig') THEN [Limit1].[Location] END AS [C8]
FROM ( SELECT TOP (10) [Filter1].[Id] AS [Id], [Filter1].[OS] AS [OS], [Filter1].[Lang] AS [Lang], [Filter1].[Arch] AS [Arch], [Filter1].[Host] AS [Host], [Filter1].[Address] AS [Address], [Filter1].[Location] AS [Location], [Filter1].[Discriminator] AS [Discriminator]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[OS] AS [OS], [Extent1].[Lang] AS [Lang], [Extent1].[Arch] AS [Arch], [Extent1].[Host] AS [Host], [Extent1].[Address] AS [Address], [Extent1].[Location] AS [Location], [Extent1].[Discriminator] AS [Discriminator], row_number() OVER (ORDER BY [Extent1].[Arch] DESC, [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[ArubaConfigs] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'ArubaMachineConfig',N'ArubaConfig')
) AS [Filter1]
WHERE [Filter1].[row_number] > 5
ORDER BY [Filter1].[Arch] DESC, [Filter1].[Id] ASC
) AS [Limit1]
WHERE [Limit1].[Discriminator] = N'ArubaMachineConfig'
) AS [Project1]
ORDER BY [Project1].[Arch] DESC, [Project1].[Id] ASC";
var query = context.Configs.OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Skip(5).Take(10).OfType<ArubaMachineConfig>();
QueryTestHelpers.VerifyDbQuery(query, expectedSql);
var results = query.ToList();
var expected = context.Configs.ToList().OrderByDescending(p => p.Arch).ThenBy(p => p.Id).Skip(5).Take(10).OfType<ArubaMachineConfig>().ToList();
QueryTestHelpers.VerifyQueryResult(expected, results, (o, i) => o.Id == i.Id);
}
}
}
}

View File

@@ -0,0 +1,142 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.Query
{
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
using System.Data.Entity.Core.Metadata.Edm;
using System.Linq;
using Xunit;
public class QueryEnumTests : FunctionalTestBase
{
private static readonly string csdl =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<Schema xmlns=""http://schemas.microsoft.com/ado/2009/11/edm"" Namespace=""MessageModel"">
<EntityContainer Name=""MessageContainer"">
<EntitySet Name=""MessageSet"" EntityType=""MessageModel.Message"" />
</EntityContainer>
<EntityType Name=""Message"">
<Key>
<PropertyRef Name=""Id"" />
</Key>
<Property Name=""Id"" Nullable=""false"" Type=""Int32"" />
<Property Name=""MessageType"" Type=""MessageModel.MessageType"" Nullable=""false""/>
</EntityType>
<EnumType Name=""MessageType"" IsFlags=""false"">
<Member Name=""Express"" />
<Member Name=""Priority"" />
<Member Name=""Ground"" />
</EnumType>
</Schema>";
private static readonly string ssdl =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<Schema Namespace=""MessageStore"" Alias=""Self"" Provider=""System.Data.SqlClient"" ProviderManifestToken=""2008"" xmlns=""http://schemas.microsoft.com/ado/2009/11/edm/ssdl"">
<EntityContainer Name=""MessageContainer_Store"">
<EntitySet Name=""MessageSet"" EntityType=""Self.Message"" Schema=""dbo"" Table=""Message"" />
</EntityContainer>
<EntityType Name=""Message"">
<Key>
<PropertyRef Name=""Id""/>
</Key>
<Property Name=""Id"" Type=""int"" Nullable=""false""/>
<Property Name=""MessageType"" Type=""int"" Nullable=""false""/>
</EntityType>
</Schema>";
private static readonly string msl =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<Mapping xmlns=""http://schemas.microsoft.com/ado/2009/11/mapping/cs"" Space=""C-S"">
<EntityContainerMapping CdmEntityContainer=""MessageContainer"" StorageEntityContainer=""MessageContainer_Store"">
<EntitySetMapping Name=""MessageSet"">
<EntityTypeMapping TypeName=""MessageModel.Message"">
<MappingFragment StoreEntitySet=""MessageSet"">
<ScalarProperty Name=""Id"" ColumnName=""Id"" />
<ScalarProperty Name=""MessageType"" ColumnName=""MessageType"" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>";
private static readonly MetadataWorkspace workspace = QueryTestHelpers.CreateMetadataWorkspace(csdl, ssdl, msl);
[Fact]
public void Simple_scan_with_Enum()
{
var entitySet = workspace.GetEntityContainer("MessageContainer", DataSpace.CSpace).GetEntitySetByName("MessageSet", false);
var query = entitySet.Scan();
var expectedSql = "SELECT [Extent1].[Id] AS [Id], [Extent1].[MessageType] AS [MessageType]FROM [dbo].[Message] AS [Extent1]";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Scan_with_casting_Enum_to_integer()
{
var entitySet = workspace.GetEntityContainer("MessageContainer", DataSpace.CSpace).GetEntitySetByName("MessageSet", false);
var query = entitySet.Scan()
.Where(
c =>
c.Property("Id").Equal(
c.Property("MessageType").CastTo(
TypeUsage.CreateDefaultTypeUsage(workspace.GetPrimitiveTypes(DataSpace.CSpace).Single(t => t.Name == "Int32")))));
var expectedSql =
"SELECT [Extent1].[Id] AS [Id], [Extent1].[MessageType] AS [MessageType] FROM [dbo].[Message] AS [Extent1] WHERE [Extent1].[Id] = CAST( [Extent1].[MessageType] AS int)";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Constant_integer_based_Enum_in_where_clause()
{
var entitySet = workspace.GetEntityContainer("MessageContainer", DataSpace.CSpace).GetEntitySetByName("MessageSet", false);
var query = entitySet.Scan()
.Where(c => c.Property("MessageType").Equal(c.Property("MessageType").ResultType.Constant(-5)));
var expectedSql =
"SELECT [Extent1].[Id] AS [Id], [Extent1].[MessageType] AS [MessageType] FROM [dbo].[Message] AS [Extent1] WHERE [Extent1].[MessageType] = -5";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
public enum MessageType
{
Express,
Priority,
Ground
};
[Fact]
public void Constant_Enum_value_in_where_clause()
{
var entitySet = workspace.GetEntityContainer("MessageContainer", DataSpace.CSpace).GetEntitySetByName("MessageSet", false);
var query = entitySet.Scan()
.Where(c => c.Property("MessageType").Equal(c.Property("MessageType").ResultType.Constant(MessageType.Express)));
var expectedSql =
"SELECT [Extent1].[Id] AS [Id], [Extent1].[MessageType] AS [MessageType] FROM [dbo].[Message] AS [Extent1] WHERE [Extent1].[MessageType] = 0";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
[Fact]
public void Null_Enum_value_in_where_clause()
{
var entitySet = workspace.GetEntityContainer("MessageContainer", DataSpace.CSpace).GetEntitySetByName("MessageSet", false);
var query = entitySet.Scan()
.Where(c => c.Property("MessageType").Equal(c.Property("MessageType").ResultType.Null()));
var expectedSql =
"SELECT [Extent1].[Id] AS [Id], [Extent1].[MessageType] AS [MessageType] FROM [dbo].[Message] AS [Extent1] WHERE [Extent1].[MessageType] = (CAST(NULL AS int))";
QueryTestHelpers.VerifyQuery(query, workspace, expectedSql);
}
}
}

File diff suppressed because it is too large Load Diff