Migrate NPocoTests
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Tests.Integration.Implementations;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests
|
||||
{
|
||||
// FIXME: npoco - is this still appropriate?
|
||||
//
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class NPocoBulkInsertTests : UmbracoIntegrationTest
|
||||
{
|
||||
private TestHelper _testHelper = new TestHelper();
|
||||
private IProfilingLogger ProfilingLogger => _testHelper.ProfilingLogger;
|
||||
|
||||
[NUnit.Framework.Ignore("Ignored because you need to configure your own SQL Server to test this with")]
|
||||
[Test]
|
||||
public void Can_Bulk_Insert_Native_Sql_Server_Bulk_Inserts()
|
||||
{
|
||||
// create the db
|
||||
// prob not what we want, this is not a real database, but hey, the test is ignored anyways
|
||||
// we'll fix this when we have proper testing infrastructure
|
||||
// var dbSqlServer = TestObjects.GetUmbracoSqlServerDatabase(new NullLogger<UmbracoDatabase>());
|
||||
var provider = ScopeProvider;
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// Still no what we want, but look above.
|
||||
var dbSqlServer = scope.Database;
|
||||
//drop the table
|
||||
dbSqlServer.Execute("DROP TABLE [umbracoServer]");
|
||||
|
||||
//re-create it
|
||||
dbSqlServer.Execute(@"CREATE TABLE [umbracoServer](
|
||||
[id] [int] IDENTITY(1,1) NOT NULL,
|
||||
[address] [nvarchar](500) NOT NULL,
|
||||
[computerName] [nvarchar](255) NOT NULL,
|
||||
[registeredDate] [datetime] NOT NULL CONSTRAINT [DF_umbracoServer_registeredDate] DEFAULT (getdate()),
|
||||
[lastNotifiedDate] [datetime] NOT NULL,
|
||||
[isActive] [bit] NOT NULL,
|
||||
[isMaster] [bit] NOT NULL,
|
||||
CONSTRAINT [PK_umbracoServer] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[id] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
)");
|
||||
var data = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
data.Add(new ServerRegistrationDto
|
||||
{
|
||||
ServerAddress = "address" + i,
|
||||
ServerIdentity = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
DateAccessed = DateTime.Now
|
||||
});
|
||||
}
|
||||
|
||||
using (var tr = dbSqlServer.GetTransaction())
|
||||
{
|
||||
dbSqlServer.BulkInsertRecords(data);
|
||||
tr.Complete();
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.That(dbSqlServer.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Bulk_Insert_Native_Sql_Bulk_Inserts()
|
||||
{
|
||||
var servers = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
servers.Add(new ServerRegistrationDto
|
||||
{
|
||||
ServerAddress = "address" + i,
|
||||
ServerIdentity = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
DateAccessed = DateTime.Now
|
||||
});
|
||||
}
|
||||
|
||||
// Act
|
||||
using (ProfilingLogger.TraceDuration<NPocoBulkInsertTests>("starting insert", "finished insert"))
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Database.BulkInsertRecords(servers);
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
// Assert
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
Assert.That(scope.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(1000));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Bulk_Insert_Native_Sql_Bulk_Inserts_Transaction_Rollback()
|
||||
{
|
||||
var servers = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
servers.Add(new ServerRegistrationDto
|
||||
{
|
||||
ServerAddress = "address" + i,
|
||||
ServerIdentity = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
DateAccessed = DateTime.Now
|
||||
});
|
||||
}
|
||||
|
||||
// Act
|
||||
using (ProfilingLogger.TraceDuration<NPocoBulkInsertTests>("starting insert", "finished insert"))
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Database.BulkInsertRecords(servers);
|
||||
//don't call complete here - the trans will be rolled back
|
||||
}
|
||||
}
|
||||
|
||||
// Assert
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
Assert.That(scope.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoServer"), Is.EqualTo(0));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Generate_Bulk_Import_Sql()
|
||||
{
|
||||
var servers = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
servers.Add(new ServerRegistrationDto
|
||||
{
|
||||
ServerAddress = "address" + i,
|
||||
ServerIdentity = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
DateAccessed = DateTime.Now
|
||||
});
|
||||
}
|
||||
|
||||
IDbCommand[] commands;
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
commands = scope.Database.GenerateBulkInsertCommands(servers.ToArray());
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.That(commands[0].CommandText,
|
||||
Is.EqualTo("INSERT INTO [umbracoServer] ([umbracoServer].[address], [umbracoServer].[computerName], [umbracoServer].[registeredDate], [umbracoServer].[lastNotifiedDate], [umbracoServer].[isActive], [umbracoServer].[isMaster]) VALUES (@0,@1,@2,@3,@4,@5), (@6,@7,@8,@9,@10,@11)"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Generate_Bulk_Import_Sql_Exceeding_Max_Params()
|
||||
{
|
||||
var servers = new List<ServerRegistrationDto>();
|
||||
for (var i = 0; i < 1500; i++)
|
||||
{
|
||||
servers.Add(new ServerRegistrationDto
|
||||
{
|
||||
ServerAddress = "address" + i,
|
||||
ServerIdentity = "computer" + i,
|
||||
DateRegistered = DateTime.Now,
|
||||
IsActive = true,
|
||||
DateAccessed = DateTime.Now,
|
||||
IsMaster = true
|
||||
});
|
||||
}
|
||||
|
||||
IDbCommand[] commands;
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
commands = scope.Database.GenerateBulkInsertCommands(servers.ToArray());
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.That(commands.Length, Is.EqualTo(5));
|
||||
foreach (var s in commands.Select(x => x.CommandText))
|
||||
{
|
||||
Assert.LessOrEqual(Regex.Matches(s, "@\\d+").Count, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,647 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
using Umbraco.Tests.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true)]
|
||||
public class NPocoFetchTests : UmbracoIntegrationTest
|
||||
{
|
||||
[SetUp]
|
||||
protected void SeedDatabase()
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
InsertData(scope.Database);
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertData(IDatabase database)
|
||||
{
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThing1 (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL
|
||||
);");
|
||||
|
||||
database.Insert(new Thing1Dto
|
||||
{
|
||||
Id = 1,
|
||||
Name = "one"
|
||||
});
|
||||
|
||||
database.Insert(new Thing1Dto
|
||||
{
|
||||
Id = 2,
|
||||
Name = "two"
|
||||
});
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThing2 (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL,
|
||||
thingId int NULL
|
||||
);");
|
||||
|
||||
database.Insert(new Thing2Dto
|
||||
{
|
||||
Id = 1,
|
||||
Name = "uno",
|
||||
ThingId = 1
|
||||
});
|
||||
|
||||
database.Insert(new Thing2Dto
|
||||
{
|
||||
Id = 2,
|
||||
Name = "due",
|
||||
ThingId = 2
|
||||
});
|
||||
|
||||
database.Insert(new Thing2Dto
|
||||
{
|
||||
Id = 3,
|
||||
Name = "tri",
|
||||
ThingId = 1
|
||||
});
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThingGroup (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL
|
||||
);");
|
||||
|
||||
database.Insert(new ThingGroupDto
|
||||
{
|
||||
Id = 1,
|
||||
Name = "g-one"
|
||||
});
|
||||
|
||||
database.Insert(new ThingGroupDto
|
||||
{
|
||||
Id = 2,
|
||||
Name = "g-two"
|
||||
});
|
||||
|
||||
database.Insert(new ThingGroupDto
|
||||
{
|
||||
Id = 3,
|
||||
Name = "g-three"
|
||||
});
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThing2Group (
|
||||
thingId int NOT NULL,
|
||||
groupId int NOT NULL
|
||||
);");
|
||||
|
||||
database.Insert(new Thing2GroupDto
|
||||
{
|
||||
ThingId = 1,
|
||||
GroupId = 1
|
||||
});
|
||||
|
||||
database.Insert(new Thing2GroupDto
|
||||
{
|
||||
ThingId = 1,
|
||||
GroupId = 2
|
||||
});
|
||||
|
||||
database.Insert(new Thing2GroupDto
|
||||
{
|
||||
ThingId = 2,
|
||||
GroupId = 2
|
||||
});
|
||||
|
||||
database.Insert(new Thing2GroupDto
|
||||
{
|
||||
ThingId = 3,
|
||||
GroupId = 3
|
||||
});
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThingA1 (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL
|
||||
);");
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThingA2 (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL
|
||||
);");
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThingA3 (
|
||||
id int PRIMARY KEY NOT NULL,
|
||||
name NVARCHAR(255) NULL
|
||||
);");
|
||||
|
||||
database.Execute(@"
|
||||
CREATE TABLE zbThingA12 (
|
||||
thing1id int NOT NULL,
|
||||
thing2id int NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL
|
||||
);");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSimple()
|
||||
{
|
||||
// fetching a simple POCO
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var sql = @"
|
||||
// SELECT zbThing1.id, zbThing1.name
|
||||
// FROM zbThing1";
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing1Dto>()
|
||||
.From<Thing1Dto>();
|
||||
|
||||
var dtos = scope.Database.Fetch<Thing1Dto>(sql);
|
||||
Assert.AreEqual(2, dtos.Count);
|
||||
Assert.AreEqual("one", dtos.First(x => x.Id == 1).Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOneToOne()
|
||||
{
|
||||
// fetching a POCO that contains the ID of another POCO,
|
||||
// and fetching that other POCO at the same time
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var sql = @"
|
||||
// SELECT zbThing2.id, zbThing2.name, zbThing2.thingId,
|
||||
// zbThing1.id Thing__id, zbThing1.name Thing__name
|
||||
// FROM zbThing2
|
||||
// JOIN zbThing1 ON zbThing2.thingId=zbThing1.id";
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing2Dto>(r => r.Select(x => x.Thing))
|
||||
.From<Thing2Dto>()
|
||||
.InnerJoin<Thing1Dto>().On<Thing2Dto, Thing1Dto>((t2, t1) => t2.ThingId == t1.Id);
|
||||
|
||||
var dtos = scope.Database.Fetch<Thing2Dto>(sql);
|
||||
Assert.AreEqual(3, dtos.Count);
|
||||
Assert.AreEqual("uno", dtos.First(x => x.Id == 1).Name);
|
||||
Assert.IsNotNull(dtos.First(x => x.Id == 1).Thing);
|
||||
Assert.AreEqual("one", dtos.First(x => x.Id == 1).Thing.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOneToManyOnOne()
|
||||
{
|
||||
// fetching a POCO that has a list of other POCOs,
|
||||
// and fetching these POCOs at the same time,
|
||||
// with a pk/fk relationship
|
||||
// for one single POCO
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, x => x.Id, @"
|
||||
// SELECT zbThing1.id AS Id, zbThing1.name AS Name,
|
||||
// zbThing2.id AS Things__Id, zbThing2.name AS Things__Name, zbThing2.thingId AS Things__ThingId
|
||||
// FROM zbThing1
|
||||
// JOIN zbThing2 ON zbThing1.id=zbThing2.thingId
|
||||
// WHERE zbThing1.id=1");
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing3Dto>(r => r.Select(x => x.Things))
|
||||
.From<Thing3Dto>()
|
||||
.InnerJoin<Thing2Dto>().On<Thing3Dto, Thing2Dto>(left => left.Id, right => right.ThingId)
|
||||
.Where<Thing3Dto>(x => x.Id == 1);
|
||||
|
||||
//var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, x => x.Id, sql);
|
||||
var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, sql);
|
||||
|
||||
Assert.AreEqual(1, dtos.Count);
|
||||
var dto1 = dtos.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto1);
|
||||
Assert.AreEqual("one", dto1.Name);
|
||||
Assert.IsNotNull(dto1.Things);
|
||||
Assert.AreEqual(2, dto1.Things.Count);
|
||||
var dto2 = dto1.Things.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto2);
|
||||
Assert.AreEqual("uno", dto2.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOneToManyOnMany()
|
||||
{
|
||||
// fetching a POCO that has a list of other POCOs,
|
||||
// and fetching these POCOs at the same time,
|
||||
// with a pk/fk relationship
|
||||
// for several POCOs
|
||||
//
|
||||
// the ORDER BY clause (matching x => x.Id) is required
|
||||
// for proper aggregation to take place
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var sql = @"
|
||||
// SELECT zbThing1.id AS Id, zbThing1.name AS Name,
|
||||
// zbThing2.id AS Things__Id, zbThing2.name AS Things__Name, zbThing2.thingId AS Things__ThingId
|
||||
// FROM zbThing1
|
||||
// JOIN zbThing2 ON zbThing1.id=zbThing2.thingId
|
||||
// ORDER BY zbThing1.id";
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing3Dto>(r => r.Select(x => x.Things)) // select Thing3Dto, and Thing2Dto for Things
|
||||
.From<Thing3Dto>()
|
||||
.InnerJoin<Thing2Dto>().On<Thing3Dto, Thing2Dto>(left => left.Id, right => right.ThingId)
|
||||
.OrderBy<Thing3Dto>(x => x.Id);
|
||||
|
||||
var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, /*x => x.Id,*/ sql);
|
||||
|
||||
Assert.AreEqual(2, dtos.Count);
|
||||
var dto1 = dtos.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto1);
|
||||
Assert.AreEqual("one", dto1.Name);
|
||||
Assert.IsNotNull(dto1.Things);
|
||||
Assert.AreEqual(2, dto1.Things.Count);
|
||||
var dto2 = dto1.Things.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto2);
|
||||
Assert.AreEqual("uno", dto2.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOneToManyOnManyTemplate()
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.SqlContext.Templates.Clear();
|
||||
|
||||
var sql = scope.SqlContext.Templates.Get("xxx", s => s
|
||||
.Select<Thing3Dto>(r => r.Select(x => x.Things)) // select Thing3Dto, and Thing2Dto for Things
|
||||
.From<Thing3Dto>()
|
||||
.InnerJoin<Thing2Dto>().On<Thing3Dto, Thing2Dto>(left => left.Id, right => right.ThingId)
|
||||
.OrderBy<Thing3Dto>(x => x.Id)).Sql();
|
||||
|
||||
// cached
|
||||
sql = scope.SqlContext.Templates.Get("xxx", s => throw new InvalidOperationException()).Sql();
|
||||
|
||||
var dtos = scope.Database.FetchOneToMany<Thing3Dto>(x => x.Things, /*x => x.Id,*/ sql);
|
||||
|
||||
Assert.AreEqual(2, dtos.Count);
|
||||
var dto1 = dtos.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto1);
|
||||
Assert.AreEqual("one", dto1.Name);
|
||||
Assert.IsNotNull(dto1.Things);
|
||||
Assert.AreEqual(2, dto1.Things.Count);
|
||||
var dto2 = dto1.Things.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto2);
|
||||
Assert.AreEqual("uno", dto2.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestManyToMany()
|
||||
{
|
||||
// fetching a POCO that has a list of other POCOs,
|
||||
// and fetching these POCOs at the same time,
|
||||
// with an n-to-n intermediate table
|
||||
//
|
||||
// the ORDER BY clause (matching x => x.Id) is required
|
||||
// for proper aggregation to take place
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var sql = @"
|
||||
// SELECT zbThing1.id, zbThing1.name, zbThingGroup.id, zbThingGroup.name
|
||||
// FROM zbThing1
|
||||
// JOIN zbThing2Group ON zbThing1.id=zbThing2Group.thingId
|
||||
// JOIN zbThingGroup ON zbThing2Group.groupId=zbThingGroup.id
|
||||
// ORDER BY zbThing1.id";
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing4Dto>(r => r.Select(x => x.Groups))
|
||||
.From<Thing4Dto>()
|
||||
.InnerJoin<Thing2GroupDto>().On<Thing4Dto, Thing2GroupDto>((t, t2g) => t.Id == t2g.ThingId)
|
||||
.InnerJoin<ThingGroupDto>().On<Thing2GroupDto, ThingGroupDto>((t2g, tg) => t2g.GroupId == tg.Id)
|
||||
.OrderBy<Thing4Dto>(x => x.Id);
|
||||
|
||||
var dtos = scope.Database.FetchOneToMany<Thing4Dto>(x => x.Groups, /*x => x.Id,*/ sql);
|
||||
|
||||
Assert.AreEqual(2, dtos.Count);
|
||||
var dto1 = dtos.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto1);
|
||||
Assert.AreEqual("one", dto1.Name);
|
||||
Assert.IsNotNull(dto1.Groups);
|
||||
Assert.AreEqual(2, dto1.Groups.Count);
|
||||
var dto2 = dto1.Groups.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto2);
|
||||
Assert.AreEqual("g-one", dto2.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculated()
|
||||
{
|
||||
// fetching a POCO that has a countof other POCOs,
|
||||
// with an n-to-n intermediate table
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
// this is the raw SQL, but it's better to use expressions and no magic strings!
|
||||
//var sql = @"
|
||||
// SELECT zbThing1.id, zbThing1.name, COUNT(zbThing2Group.groupId) as groupCount
|
||||
// FROM zbThing1
|
||||
// JOIN zbThing2Group ON zbThing1.id=zbThing2Group.thingId
|
||||
// GROUP BY zbThing1.id, zbThing1.name";
|
||||
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.Select<Thing1Dto>()
|
||||
.Append(", COUNT(zbThing2Group.groupId) AS groupCount") // FIXME:
|
||||
.From<Thing1Dto>()
|
||||
.InnerJoin<Thing2GroupDto>().On<Thing1Dto, Thing2GroupDto>((t, t2g) => t.Id == t2g.ThingId)
|
||||
.GroupBy<Thing1Dto>(x => x.Id, x => x.Name);
|
||||
|
||||
var dtos = scope.Database.Fetch<Thing5Dto>(sql);
|
||||
|
||||
Assert.AreEqual(2, dtos.Count);
|
||||
var dto1 = dtos.FirstOrDefault(x => x.Id == 1);
|
||||
Assert.IsNotNull(dto1);
|
||||
Assert.AreEqual("one", dto1.Name);
|
||||
Assert.AreEqual(2, dto1.GroupCount);
|
||||
var dto2 = dtos.FirstOrDefault(x => x.Id == 2);
|
||||
Assert.IsNotNull(dto2);
|
||||
Assert.AreEqual("two", dto2.Name);
|
||||
Assert.AreEqual(1, dto2.GroupCount);
|
||||
}
|
||||
}
|
||||
|
||||
// no test for ReferenceType.Foreign at the moment
|
||||
// it's more or less OneToOne, but NPoco manages the keys when
|
||||
// inserting or updating
|
||||
|
||||
[Test]
|
||||
public void TestSql()
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
var sql = scope.SqlContext.Sql()
|
||||
.SelectAll()
|
||||
.From<Thing1Dto>()
|
||||
.Where<Thing1Dto>(x => x.Id == 1);
|
||||
|
||||
var dto = scope.Database.Fetch<Thing1Dto>(sql).FirstOrDefault();
|
||||
Assert.IsNotNull(dto);
|
||||
Assert.AreEqual("one", dto.Name);
|
||||
|
||||
//var sql2 = new Sql(sql.SQL, new { id = 1 });
|
||||
//WriteSql(sql2);
|
||||
//dto = Database.Fetch<Thing1Dto>(sql2).FirstOrDefault();
|
||||
//Assert.IsNotNull(dto);
|
||||
//Assert.AreEqual("one", dto.Name);
|
||||
|
||||
var sql3 = new Sql(sql.SQL, 1);
|
||||
dto = scope.Database.Fetch<Thing1Dto>(sql3).FirstOrDefault();
|
||||
Assert.IsNotNull(dto);
|
||||
Assert.AreEqual("one", dto.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMultipleOneToOne()
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
var tA1A = new ThingA1Dto { Id = 1, Name = "a1_a" };
|
||||
scope.Database.Insert(tA1A);
|
||||
var tA1B = new ThingA1Dto { Id = 2, Name = "a1_b" };
|
||||
scope.Database.Insert(tA1B);
|
||||
var tA1C = new ThingA1Dto { Id = 3, Name = "a1_c" };
|
||||
scope.Database.Insert(tA1C);
|
||||
|
||||
var tA2A = new ThingA2Dto { Id = 1, Name = "a2_a" };
|
||||
scope.Database.Insert(tA2A);
|
||||
var tA2B = new ThingA2Dto { Id = 2, Name = "a2_b" };
|
||||
scope.Database.Insert(tA2B);
|
||||
var tA2C = new ThingA2Dto { Id = 3, Name = "a2_c" };
|
||||
scope.Database.Insert(tA2C);
|
||||
|
||||
var tA3A = new ThingA3Dto { Id = 1, Name = "a3_a" };
|
||||
scope.Database.Insert(tA3A);
|
||||
var tA3B = new ThingA3Dto { Id = 2, Name = "a3_b" };
|
||||
scope.Database.Insert(tA3B);
|
||||
|
||||
var k1 = new ThingA12Dto { Name = "a", Thing1Id = tA1A.Id, Thing2Id = tA2A.Id };
|
||||
scope.Database.Insert(k1);
|
||||
var k2 = new ThingA12Dto { Name = "B", Thing1Id = tA1A.Id, Thing2Id = tA2B.Id };
|
||||
scope.Database.Insert(k2);
|
||||
|
||||
var sql = @"SELECT a1.id, a1.name,
|
||||
a2.id AS T2A__Id, a2.name AS T2A__Name, a3.id AS T2A__T3__Id, a3.name AS T2A__T3__Name,
|
||||
a2x.id AS T2B__Id, a2x.name AS T2B__Name, a3x.id AS T2B__T3__Id, a3x.name AS T2B__T3__Name
|
||||
FROM zbThingA1 a1
|
||||
JOIN zbThingA12 a12 ON a1.id=a12.thing1id AND a12.name='a'
|
||||
JOIN zbThingA2 a2 ON a12.thing2id=a2.id
|
||||
JOIN zbThingA3 a3 ON a2.id=a3.id
|
||||
JOIN zbThingA12 a12x ON a1.id=a12x.thing1id AND a12x.name='b'
|
||||
JOIN zbThingA2 a2x ON a12x.thing2id=a2x.id
|
||||
JOIN zbThingA3 a3x ON a2x.id=a3x.id
|
||||
";
|
||||
|
||||
var ts = scope.Database.Fetch<ThingA1Dto>(sql);
|
||||
Assert.AreEqual(1, ts.Count);
|
||||
|
||||
var t = ts.First();
|
||||
Assert.AreEqual("a1_a", t.Name);
|
||||
Assert.AreEqual("a2_a", t.T2A.Name);
|
||||
Assert.AreEqual("a2_b", t.T2B.Name);
|
||||
|
||||
Assert.AreEqual("a3_a", t.T2A.T3.Name);
|
||||
Assert.AreEqual("a3_b", t.T2B.T3.Name);
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
[TableName("zbThing1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing1Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThing2")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing2Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("thingId")]
|
||||
public int ThingId { get; set; }
|
||||
|
||||
// reference is required else value remains null
|
||||
// columnName indicates which column has the id, referenceMembreName not needed if PK
|
||||
[Reference(ReferenceType.OneToOne, ColumnName = "thingId"/*, ReferenceMemberName="id"*/)]
|
||||
public Thing1Dto Thing { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThing1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing3Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
// reference is required else FetchOneToMany aggregation does not happen
|
||||
// does not seem to require ReferenceMemberName="thingId", ColumnName not needed if PK
|
||||
[Reference(ReferenceType.Many/*, ColumnName="id", ReferenceMemberName="thingId"*/)]
|
||||
public List<Thing2Dto> Things { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThingGroup")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class ThingGroupDto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThing2Group")]
|
||||
[PrimaryKey("thingId, groupId", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing2GroupDto
|
||||
{
|
||||
[Column("thingId")]
|
||||
public int ThingId { get; set; }
|
||||
|
||||
[Column("groupId")]
|
||||
public int GroupId { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThing1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing4Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
// reference is required else FetchOneToMany aggregation does not happen
|
||||
// not sure ColumnName nor ReferenceMemberName make much sense here
|
||||
[Reference(ReferenceType.Many/*, ColumnName="id", ReferenceMemberName="thingId"*/)]
|
||||
public List<ThingGroupDto> Groups { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThing1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Thing5Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("groupCount")]
|
||||
[ResultColumn] // not included in insert/update, not sql-generated
|
||||
//[ComputedColumn] // not included in insert/update, sql-generated
|
||||
public int GroupCount { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThingA1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class ThingA1Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne)]
|
||||
public ThingA2Dto T2A { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne)]
|
||||
public ThingA2Dto T2B { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThingA2")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class ThingA2Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne)]
|
||||
public ThingA3Dto T3 { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThingA3")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class ThingA3Dto
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[TableName("zbThingA12")]
|
||||
[ExplicitColumns]
|
||||
public class ThingA12Dto
|
||||
{
|
||||
[Column("thing1id")]
|
||||
public int Thing1Id { get; set; }
|
||||
|
||||
[Column("thing2id")]
|
||||
public int Thing2Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
using System.Collections.Generic;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
using Umbraco.Tests.Testing;
|
||||
using static Umbraco.Core.Persistence.SqlExtensionsStatics;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class NPocoSqlExtensionsTests : UmbracoIntegrationTest
|
||||
{
|
||||
private ISqlContext SqlContext => GetRequiredService<ISqlContext>();
|
||||
|
||||
private Sql<ISqlContext> Sql()
|
||||
{
|
||||
return NPoco.Sql.BuilderFor(SqlContext);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhereTest()
|
||||
{
|
||||
var sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => x.LanguageId == null);
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] is null))", sql.SQL, sql.SQL);
|
||||
|
||||
sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => x.LanguageId == 123);
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))", sql.SQL, sql.SQL);
|
||||
|
||||
var id = 123;
|
||||
|
||||
sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => x.LanguageId == id);
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))", sql.SQL, sql.SQL);
|
||||
|
||||
int? nid = 123;
|
||||
|
||||
sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => x.LanguageId == nid);
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))", sql.SQL, sql.SQL);
|
||||
|
||||
// but the above comparison fails if @0 is null
|
||||
// what we want is something similar to:
|
||||
|
||||
sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => (nid == null && x.LanguageId == null) || (nid != null && x.LanguageId == nid));
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE ((((@0 is null) AND ([umbracoPropertyData].[languageId] is null)) OR ((@1 is not null) AND ([umbracoPropertyData].[languageId] = @2))))", sql.SQL, sql.SQL);
|
||||
|
||||
// new SqlNullableEquals method does it automatically
|
||||
// 'course it would be nicer if '==' could do it
|
||||
// see note in ExpressionVisitorBase for SqlNullableEquals
|
||||
|
||||
//sql = new Sql<ISqlContext>(SqlContext)
|
||||
// .Select("*")
|
||||
// .From<PropertyDataDto>()
|
||||
// .Where<PropertyDataDto>(x => x.LanguageId.SqlNullableEquals(nid));
|
||||
//Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE ((((@0 is null) AND ([umbracoPropertyData].[languageId] is null)) OR ((@0 is not null) AND ([umbracoPropertyData].[languageId] = @0))))", sql.SQL, sql.SQL);
|
||||
|
||||
// but, the expression above fails with SQL CE, 'specified argument for the function is not valid' in 'isnull' function
|
||||
// so... compare with fallback values
|
||||
|
||||
sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.Where<PropertyDataDto>(x => x.LanguageId.SqlNullableEquals(nid, -1));
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE ((COALESCE([umbracoPropertyData].[languageId],@0) = COALESCE(@1,@0)))", sql.SQL, sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SqlNullableEqualsTest()
|
||||
{
|
||||
int? a, b;
|
||||
a = b = null;
|
||||
Assert.IsTrue(a.SqlNullableEquals(b, -1));
|
||||
b = 2;
|
||||
Assert.IsFalse(a.SqlNullableEquals(b, -1));
|
||||
a = 2;
|
||||
Assert.IsTrue(a.SqlNullableEquals(b, -1));
|
||||
b = null;
|
||||
Assert.IsFalse(a.SqlNullableEquals(b, -1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhereInValueFieldTest()
|
||||
{
|
||||
var sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.WhereIn<NodeDto>(x => x.NodeId, new[] { 1, 2, 3 });
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoNode]\nWHERE ([umbracoNode].[id] IN (@0,@1,@2))", sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhereInObjectFieldTest()
|
||||
{
|
||||
// this test used to fail because x => x.Text was evaluated as a lambda
|
||||
// and returned "[umbracoNode].[text] = @0"... had to fix WhereIn.
|
||||
|
||||
var sql = new Sql<ISqlContext>(SqlContext)
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.WhereIn<NodeDto>(x => x.Text, new[] { "a", "b", "c" });
|
||||
Assert.AreEqual("SELECT *\nFROM [umbracoNode]\nWHERE ([umbracoNode].[text] IN (@0,@1,@2))", sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectTests()
|
||||
{
|
||||
// select the whole DTO
|
||||
var sql = Sql()
|
||||
.Select<Dto1>()
|
||||
.From<Dto1>();
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value] FROM [dto1]", sql.SQL.NoCrLf());
|
||||
|
||||
// select only 1 field
|
||||
sql = Sql()
|
||||
.Select<Dto1>(x => x.Id)
|
||||
.From<Dto1>();
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id] FROM [dto1]", sql.SQL.NoCrLf());
|
||||
|
||||
// select 2 fields
|
||||
sql = Sql()
|
||||
.Select<Dto1>(x => x.Id, x => x.Name)
|
||||
.From<Dto1>();
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name] FROM [dto1]", sql.SQL.NoCrLf());
|
||||
|
||||
// select the whole DTO and a referenced DTO
|
||||
sql = Sql()
|
||||
.Select<Dto1>(r => r.Select(x => x.Dto2))
|
||||
.From<Dto1>()
|
||||
.InnerJoin<Dto2>().On<Dto1, Dto2>(left => left.Id, right => right.Dto1Id);
|
||||
Assert.AreEqual(@"SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
|
||||
, [dto2].[id] AS [Dto2__Id], [dto2].[dto1id] AS [Dto2__Dto1Id], [dto2].[name] AS [Dto2__Name]
|
||||
FROM [dto1]
|
||||
INNER JOIN [dto2] ON [dto1].[id] = [dto2].[dto1id]".NoCrLf(), sql.SQL.NoCrLf(), sql.SQL);
|
||||
|
||||
// select the whole DTO and nested referenced DTOs
|
||||
sql = Sql()
|
||||
.Select<Dto1>(r => r.Select(x => x.Dto2, r1 => r1.Select(x => x.Dto3)))
|
||||
.From<Dto1>()
|
||||
.InnerJoin<Dto2>().On<Dto1, Dto2>(left => left.Id, right => right.Dto1Id)
|
||||
.InnerJoin<Dto3>().On<Dto2, Dto3>(left => left.Id, right => right.Dto2Id);
|
||||
Assert.AreEqual(@"SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
|
||||
, [dto2].[id] AS [Dto2__Id], [dto2].[dto1id] AS [Dto2__Dto1Id], [dto2].[name] AS [Dto2__Name]
|
||||
, [dto3].[id] AS [Dto2__Dto3__Id], [dto3].[dto2id] AS [Dto2__Dto3__Dto2Id], [dto3].[name] AS [Dto2__Dto3__Name]
|
||||
FROM [dto1]
|
||||
INNER JOIN [dto2] ON [dto1].[id] = [dto2].[dto1id]
|
||||
INNER JOIN [dto3] ON [dto2].[id] = [dto3].[dto2id]".NoCrLf(), sql.SQL.NoCrLf());
|
||||
|
||||
// select the whole DTO and referenced DTOs
|
||||
sql = Sql()
|
||||
.Select<Dto1>(r => r.Select(x => x.Dto2s))
|
||||
.From<Dto1>()
|
||||
.InnerJoin<Dto2>().On<Dto1, Dto2>(left => left.Id, right => right.Dto1Id);
|
||||
Assert.AreEqual(@"SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
|
||||
, [dto2].[id] AS [Dto2s__Id], [dto2].[dto1id] AS [Dto2s__Dto1Id], [dto2].[name] AS [Dto2s__Name]
|
||||
FROM [dto1]
|
||||
INNER JOIN [dto2] ON [dto1].[id] = [dto2].[dto1id]".NoCrLf(), sql.SQL.NoCrLf());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectAliasTests()
|
||||
{
|
||||
// and select - not good
|
||||
var sql = Sql()
|
||||
.Select<Dto1>(x => x.Id)
|
||||
.Select<Dto2>(x => x.Id);
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id] SELECT [dto2].[id] AS [Id]".NoCrLf(), sql.SQL.NoCrLf());
|
||||
|
||||
// and select - good
|
||||
sql = Sql()
|
||||
.Select<Dto1>(x => x.Id)
|
||||
.AndSelect<Dto2>(x => x.Id);
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id] , [dto2].[id] AS [Id]".NoCrLf(), sql.SQL.NoCrLf());
|
||||
|
||||
// and select + alias
|
||||
sql = Sql()
|
||||
.Select<Dto1>(x => x.Id)
|
||||
.AndSelect<Dto2>(x => Alias(x.Id, "id2"));
|
||||
Assert.AreEqual("SELECT [dto1].[id] AS [Id] , [dto2].[id] AS [id2]".NoCrLf(), sql.SQL.NoCrLf());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateTests()
|
||||
{
|
||||
var sql = Sql()
|
||||
.Update<DataTypeDto>(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias");
|
||||
}
|
||||
|
||||
[TableName("dto1")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Dto1
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
[Column("value")]
|
||||
public int Value { get; set; }
|
||||
[Reference]
|
||||
public Dto2 Dto2 { get; set; }
|
||||
[Reference]
|
||||
public List<Dto2> Dto2s { get; set; }
|
||||
}
|
||||
|
||||
[TableName("dto2")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Dto2
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
[Column("dto1id")]
|
||||
public int Dto1Id { get; set; }
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
[Reference]
|
||||
public Dto3 Dto3 { get; set; }
|
||||
}
|
||||
|
||||
[TableName("dto3")]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
public class Dto3
|
||||
{
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
[Column("dto2id")]
|
||||
public int Dto2Id { get; set; }
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using Moq;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Persistance.SqlCe;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class NPocoSqlTemplateTests
|
||||
{
|
||||
[Test]
|
||||
public void SqlTemplates()
|
||||
{
|
||||
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, Mock.Of<IPocoDataFactory>());
|
||||
var sqlTemplates = new SqlTemplates(sqlContext);
|
||||
|
||||
// this can be used for queries that we know we'll use a *lot* and
|
||||
// want to cache as a (static) template for ever, and ever - note
|
||||
// that using a MemoryCache would allow us to set a size limit, or
|
||||
// something equivalent, to reduce risk of memory explosion
|
||||
var sql = sqlTemplates.Get("xxx", s => s
|
||||
.SelectAll()
|
||||
.From("zbThing1")
|
||||
.Where("id=@id", new { id = SqlTemplate.Arg("id") })).Sql(new { id = 1 });
|
||||
|
||||
var sql2 = sqlTemplates.Get("xxx", x => throw new InvalidOperationException("Should be cached.")).Sql(1);
|
||||
|
||||
var sql3 = sqlTemplates.Get("xxx", x => throw new InvalidOperationException("Should be cached.")).Sql(new { id = 1 });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SqlTemplateArgs()
|
||||
{
|
||||
var mappers = new NPoco.MapperCollection { new PocoMapper() };
|
||||
var factory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, mappers).Init());
|
||||
|
||||
var sqlContext = new SqlContext(new SqlCeSyntaxProvider(), DatabaseType.SQLCe, factory);
|
||||
var sqlTemplates = new SqlTemplates(sqlContext);
|
||||
|
||||
const string sqlBase = "SELECT [zbThing1].[id] AS [Id], [zbThing1].[name] AS [Name] FROM [zbThing1] WHERE ";
|
||||
|
||||
var template = sqlTemplates.Get("sql1", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Name == SqlTemplate.Arg<string>("value")));
|
||||
|
||||
var sql = template.Sql("foo");
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(123);
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(123, sql.Arguments[0]);
|
||||
|
||||
template = sqlTemplates.Get("sql2", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Name == SqlTemplate.Arg<string>("value")));
|
||||
|
||||
sql = template.Sql(new { value = "foo" });
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(new { value = 123 });
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[name] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(123, sql.Arguments[0]);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => template.Sql(new { xvalue = 123 }));
|
||||
Assert.Throws<InvalidOperationException>(() => template.Sql(new { value = 123, xvalue = 456 }));
|
||||
|
||||
var i = 666;
|
||||
|
||||
template = sqlTemplates.Get("sql3", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Id == i));
|
||||
|
||||
sql = template.Sql("foo");
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(123);
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(123, sql.Arguments[0]);
|
||||
|
||||
// but we cannot name them, because the arg name is the value of "i"
|
||||
// so we have to explicitely create the argument
|
||||
|
||||
template = sqlTemplates.Get("sql4", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Id == SqlTemplate.Arg<int>("i")));
|
||||
|
||||
sql = template.Sql("foo");
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(123);
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(123, sql.Arguments[0]);
|
||||
|
||||
// and thanks to a patched visitor, this now works
|
||||
|
||||
sql = template.Sql(new { i = "foo" });
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(new { i = 123 });
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(123, sql.Arguments[0]);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => template.Sql(new { j = 123 }));
|
||||
Assert.Throws<InvalidOperationException>(() => template.Sql(new { i = 123, j = 456 }));
|
||||
|
||||
// now with more arguments
|
||||
|
||||
template = sqlTemplates.Get("sql4a", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Id == SqlTemplate.Arg<int>("i") && x.Name == SqlTemplate.Arg<string>("name")));
|
||||
sql = template.Sql(0, 1);
|
||||
Assert.AreEqual(sqlBase + "((([zbThing1].[id] = @0) AND ([zbThing1].[name] = @1)))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(0, sql.Arguments[0]);
|
||||
Assert.AreEqual(1, sql.Arguments[1]);
|
||||
|
||||
template = sqlTemplates.Get("sql4b", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Id == SqlTemplate.Arg<int>("i"))
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Name == SqlTemplate.Arg<string>("name")));
|
||||
sql = template.Sql(0, 1);
|
||||
Assert.AreEqual(sqlBase + "(([zbThing1].[id] = @0)) AND (([zbThing1].[name] = @1))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(0, sql.Arguments[0]);
|
||||
Assert.AreEqual(1, sql.Arguments[1]);
|
||||
|
||||
// works, magic
|
||||
|
||||
template = sqlTemplates.Get("sql5", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.WhereIn<NPocoFetchTests.Thing1Dto>(x => x.Id, SqlTemplate.ArgIn<int>("i")));
|
||||
|
||||
sql = template.Sql("foo");
|
||||
Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
|
||||
sql = template.Sql(new[] { 1, 2, 3 });
|
||||
Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0,@1,@2))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(3, sql.Arguments.Length);
|
||||
Assert.AreEqual(1, sql.Arguments[0]);
|
||||
Assert.AreEqual(2, sql.Arguments[1]);
|
||||
Assert.AreEqual(3, sql.Arguments[2]);
|
||||
|
||||
template = sqlTemplates.Get("sql5a", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
.WhereIn<NPocoFetchTests.Thing1Dto>(x => x.Id, SqlTemplate.ArgIn<int>("i"))
|
||||
.Where<NPocoFetchTests.Thing1Dto>(x => x.Name == SqlTemplate.Arg<string>("name")));
|
||||
|
||||
sql = template.Sql("foo", "bar");
|
||||
Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0)) AND (([zbThing1].[name] = @1))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual("foo", sql.Arguments[0]);
|
||||
Assert.AreEqual("bar", sql.Arguments[1]);
|
||||
|
||||
sql = template.Sql(new[] { 1, 2, 3 }, "bar");
|
||||
Assert.AreEqual(sqlBase + "([zbThing1].[id] IN (@0,@1,@2)) AND (([zbThing1].[name] = @3))", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(4, sql.Arguments.Length);
|
||||
Assert.AreEqual(1, sql.Arguments[0]);
|
||||
Assert.AreEqual(2, sql.Arguments[1]);
|
||||
Assert.AreEqual(3, sql.Arguments[2]);
|
||||
Assert.AreEqual("bar", sql.Arguments[3]);
|
||||
|
||||
// note however that using WhereIn in a template means that the SQL is going
|
||||
// to be parsed and arguments are going to be expanded etc - it *may* be a better
|
||||
// idea to just add the WhereIn to a templated, immutable SQL template
|
||||
|
||||
// more fun...
|
||||
|
||||
template = sqlTemplates.Get("sql6", s => s.Select<NPocoFetchTests.Thing1Dto>().From<NPocoFetchTests.Thing1Dto>()
|
||||
// do NOT do this, this is NOT a visited expression
|
||||
//.Append(" AND whatever=@0", SqlTemplate.Arg<string>("j"))
|
||||
|
||||
// does not work anymore - due to proper TemplateArg
|
||||
//// instead, directly name the argument
|
||||
//.Append("AND whatever=@0", "j")
|
||||
//.Append("AND whatever=@0", "k")
|
||||
|
||||
// instead, explicitely create the argument
|
||||
.Append("AND whatever=@0", SqlTemplate.Arg("j"))
|
||||
.Append("AND whatever=@0", SqlTemplate.Arg("k"))
|
||||
);
|
||||
|
||||
sql = template.Sql(new { j = new[] { 1, 2, 3 }, k = "oops" });
|
||||
Assert.AreEqual(sqlBase.TrimEnd("WHERE ") + "AND whatever=@0,@1,@2 AND whatever=@3", sql.SQL.NoCrLf());
|
||||
Assert.AreEqual(4, sql.Arguments.Length);
|
||||
Assert.AreEqual(1, sql.Arguments[0]);
|
||||
Assert.AreEqual(2, sql.Arguments[1]);
|
||||
Assert.AreEqual(3, sql.Arguments[2]);
|
||||
Assert.AreEqual("oops", sql.Arguments[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
using Umbraco.Tests.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.NPocoTests
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class NPocoSqlTests : UmbracoIntegrationTest
|
||||
{
|
||||
private ISqlContext SqlContext => GetRequiredService<ISqlContext>();
|
||||
|
||||
private Sql<ISqlContext> Sql()
|
||||
{
|
||||
return NPoco.Sql.BuilderFor(SqlContext);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Starts_With_Additional_Parameters()
|
||||
{
|
||||
var content = new NodeDto() { NodeId = 123, Path = "-1,123" };
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Path.SqlStartsWith(content.Path, TextColumnType.NVarchar));
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[path]) LIKE upper(@0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(content.Path + "%", sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Starts_With_By_Variable()
|
||||
{
|
||||
var content = new NodeDto() {NodeId = 123, Path = "-1,123"};
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Path.StartsWith(content.Path) && x.NodeId != content.NodeId);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((upper([umbracoNode].[path]) LIKE upper(@0) AND ([umbracoNode].[id] <> @1)))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(content.Path + "%", sql.Arguments[0]);
|
||||
Assert.AreEqual(content.NodeId, sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Not_Starts_With()
|
||||
{
|
||||
const int level = 1;
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Level == level && !x.Path.StartsWith("-20"));
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[level] = @0) AND NOT (upper([umbracoNode].[path]) LIKE upper(@1))))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(level, sql.Arguments[0]);
|
||||
Assert.AreEqual("-20%", sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_EqualsFalse_Starts_With()
|
||||
{
|
||||
const int level = 1;
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Level == level && x.Path.StartsWith("-20") == false);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[level] = @0) AND NOT (upper([umbracoNode].[path]) LIKE upper(@1))))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(level, sql.Arguments[0]);
|
||||
Assert.AreEqual("-20%", sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Equals_Clause()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Text.Equals("Hello@world.com"));
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[text]) = upper(@0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("Hello@world.com", sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_False_Boolean()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Trashed == false);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(true, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_EqualsFalse_Boolean()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>().Where<NodeDto>(x => x.Trashed == false);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(true, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Boolean()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Trashed);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[trashed] = @0)", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(true, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_ToUpper()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Text.ToUpper() == "hello".ToUpper());
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((upper([umbracoNode].[text]) = upper(@0)))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("hello", sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_ToString()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Text == 1.ToString());
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[text] = @0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("1", sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Wildcard()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Text.StartsWith("D"));
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (upper([umbracoNode].[text]) LIKE upper(@0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual("D%", sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_Single_Constant()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeId == 2);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[id] = @0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(2, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_And_Constant()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeId != 2 && x.NodeId != 3);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[id] <> @0) AND ([umbracoNode].[id] <> @1)))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(2, sql.Arguments[0]);
|
||||
Assert.AreEqual(3, sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_Or_Constant()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.Text == "hello" || x.NodeId == 3);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ((([umbracoNode].[text] = @0) OR ([umbracoNode].[id] = @1)))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual("hello", sql.Arguments[0]);
|
||||
Assert.AreEqual(3, sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Null()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>().WhereNull<NodeDto>(x => x.NodeId);
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[id] IS NULL))", sql.SQL.Replace("\n", " "));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Not_Null()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>().WhereNotNull<NodeDto>(x => x.NodeId);
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (([umbracoNode].[id] IS NOT NULL))", sql.SQL.Replace("\n", " "));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Any()
|
||||
{
|
||||
var sql = Sql().SelectAll().From<NodeDto>().WhereAny(
|
||||
s => s.Where<NodeDto>(x => x.NodeId == 1),
|
||||
s => s.Where<NodeDto>(x => x.NodeId == 2));
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (( (([umbracoNode].[id] = @0)) ) OR ( (([umbracoNode].[id] = @1)) ))", sql.SQL.Replace("\n", " "));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Select_From_With_Type()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll().From($"[{Constants.DatabaseSchema.Tables.Content}]");
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll().From<ContentDto>();
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_InnerJoin_With_Types()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll()
|
||||
.From($"[{Constants.DatabaseSchema.Tables.DocumentVersion}]")
|
||||
.InnerJoin($"[{Constants.DatabaseSchema.Tables.ContentVersion}]")
|
||||
.On($"[{Constants.DatabaseSchema.Tables.DocumentVersion}].[id] = [{Constants.DatabaseSchema.Tables.ContentVersion}].[id]");
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll().From<DocumentVersionDto>()
|
||||
.InnerJoin<ContentVersionDto>()
|
||||
.On<DocumentVersionDto, ContentVersionDto>(left => left.Id, right => right.Id);
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_OrderBy_With_Type()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll().From($"[{Constants.DatabaseSchema.Tables.Content}]").OrderBy($"([{Constants.DatabaseSchema.Tables.Content}].[contentTypeId])");
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll().From<ContentDto>().OrderBy<ContentDto>(x => x.ContentTypeId);
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_GroupBy_With_Type()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll().From($"[{Constants.DatabaseSchema.Tables.Content}]").GroupBy($"[{Constants.DatabaseSchema.Tables.Content}].[contentTypeId]");
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll().From<ContentDto>().GroupBy<ContentDto>(x => x.ContentTypeId);
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Use_Where_Predicate()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll().From($"[{Constants.DatabaseSchema.Tables.Content}]").Where($"([{Constants.DatabaseSchema.Tables.Content}].[nodeId] = @0)", 1045);
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll().From<ContentDto>().Where<ContentDto>(x => x.NodeId == 1045);
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Use_Where_And_Predicate()
|
||||
{
|
||||
var expected = Sql();
|
||||
expected.SelectAll()
|
||||
.From($"[{Constants.DatabaseSchema.Tables.Content}]")
|
||||
.Where($"([{Constants.DatabaseSchema.Tables.Content}].[nodeId] = @0)", 1045)
|
||||
.Where($"([{Constants.DatabaseSchema.Tables.Content}].[contentTypeId] = @0)", 1050);
|
||||
|
||||
var sql = Sql();
|
||||
sql.SelectAll()
|
||||
.From<ContentDto>()
|
||||
.Where<ContentDto>(x => x.NodeId == 1045)
|
||||
.Where<ContentDto>(x => x.ContentTypeId == 1050);
|
||||
|
||||
Assert.That(sql.SQL, Is.EqualTo(expected.SQL));
|
||||
|
||||
Debug.Print(sql.SQL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ForUpdate()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
|
||||
var sql = Sql()
|
||||
.SelectAll()
|
||||
.From<UserLoginDto>()
|
||||
.Where<UserLoginDto>(x => x.SessionId == sessionId);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoUserLogin] WHERE (([umbracoUserLogin].[sessionId] = @0))", sql.SQL.NoCrLf());
|
||||
|
||||
sql = sql.ForUpdate();
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoUserLogin] WITH (UPDLOCK) WHERE (([umbracoUserLogin].[sessionId] = @0))", sql.SQL.NoCrLf());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user