Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multi keys. #241

Merged
merged 2 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,7 @@ public virtual SqlQuery GetSelectAll(Expression<Func<TEntity, bool>>? predicate,
/// <inheritdoc />
public virtual SqlQuery GetSelectById(object id, FilterData? filterData, params Expression<Func<TEntity, object>>[] includes)
{
if (KeySqlProperties.Length != 1)
throw new NotSupportedException("GetSelectById support only 1 key");

var keyProperty = KeySqlProperties[0];
var param = GetKeysParam(id);

var sqlQuery = InitBuilderSelect(includes.Length == 0, filterData);

Expand All @@ -280,20 +277,16 @@ public virtual SqlQuery GetSelectById(object id, FilterData? filterData, params
.Append(" ");
}

IDictionary<string, object> dictionary = new Dictionary<string, object>
{
{ keyProperty.PropertyName, id }
};

sqlQuery.SqlBuilder
.Append("WHERE ")
.Append(TableName)
.Append(".")
.Append(keyProperty.ColumnName)
.Append(" = ")
.Append(ParameterSymbol)
.Append(keyProperty.PropertyName)
.Append(" ");
for (var index = 0; index < KeySqlProperties.Length; index++)
sqlQuery.SqlBuilder
.Append(index == 0 ? "WHERE " : "AND ")
.Append(TableName)
.Append(".")
.Append(KeySqlProperties[index].ColumnName)
.Append(" = ")
.Append(ParameterSymbol)
.Append(KeySqlProperties[index].PropertyName)
.Append(" ");

if (LogicalDelete)
sqlQuery.SqlBuilder
Expand All @@ -313,10 +306,33 @@ public virtual SqlQuery GetSelectById(object id, FilterData? filterData, params
sqlQuery.SqlBuilder.Append("LIMIT 1");
}

sqlQuery.SetParam(dictionary);
sqlQuery.SetParam(param);
return sqlQuery;
}

internal object GetKeysParam(object id)
{
if (KeySqlProperties.Length < 2)
return new Dictionary<string, object> { { KeySqlProperties[0].PropertyName, id } };

if (id is not Array array) return id;

if (array.Length != KeySqlProperties.Length)
throw new ArgumentException("GetSelectById id(Array) length not equals key properties count", nameof(id));

var dictionary = new Dictionary<string, object>();

for (var index = 0; index < KeySqlProperties.Length; index++)
{
if (array.GetValue(index) is not { } value)
throw new ArgumentException($"Key value is null in {index}", nameof(id));

dictionary[KeySqlProperties[index].PropertyName] = value;
}

return dictionary;
}

/// <inheritdoc />
public virtual SqlQuery GetSelectBetween(object from, object to, FilterData? filterData, Expression<Func<TEntity, object>> btwField)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public static void Execute(IDbContext db)
db.Users.Insert(new User { Name = "TestName0", PhoneId = 1 });
db.Cars.Insert(new Car { Name = "TestCar0", UserId = 1 });
db.Cars.Insert(new Car { Name = "TestCar1", UserId = 1 });

db.Reports.Insert(new Report() { Id = 1, AnotherId = 2, UserId = 1 });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ public void FindById()
Assert.Equal("TestName1", user.Name);
}

[Fact]
public void FindById_MultiKeys()
{
Assert.NotNull(Db.Reports.FindById(new[] { 1, 2 }));
}

[Fact]
public async void FindByIdAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,15 @@ public static void SelectBetweenWithoutLogicalDeleteBraclets()
"WHERE [Addresses].[Id] BETWEEN '1' AND '10'", sqlQuery.GetSql());
}

[Fact]
public static void SelectById_MultiKeys()
{
ISqlGenerator<Report> userSqlGenerator = new SqlGenerator<Report>(_sqlConnector, true);
var sqlQuery = userSqlGenerator.GetSelectById(new[] { 1, 2 }, null);

Assert.Equal("SELECT TOP 1 [Reports].[Id], [Reports].[AnotherId], [Reports].[UserId] FROM [Reports] WHERE [Reports].[Id] = @Id AND [Reports].[AnotherId] = @AnotherId", sqlQuery.GetSql());
}

[Fact]
public static void SelectById()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using MicroOrm.Dapper.Repositories.SqlGenerator;
using MicroOrm.Dapper.Repositories.Tests.Classes;
using Xunit;

namespace MicroOrm.Dapper.Repositories.Tests.SqlGeneratorTests;

public class SqlGeneratorTests
{
public class GetKeysParamTest
{
[Fact]
public void KeyValuesLengthNotEqualKeysCount()
{
var sqlGenerator = new SqlGenerator<Report>();

var ex = Assert.Throws<ArgumentException>(() => sqlGenerator.GetKeysParam(new[] { 1 }));

Assert.Equal("id", ex.ParamName);
Assert.StartsWith("GetSelectById id(Array) length not equals key properties count", ex.Message);
}

[Fact]
public void KeyValuesContainsNull()
{
var sqlGenerator = new SqlGenerator<Report>();

var ex = Assert.Throws<ArgumentException>(() => sqlGenerator.GetKeysParam(new object[] { 1, null }));

Assert.Equal("id", ex.ParamName);
Assert.StartsWith("Key value is null in 1", ex.Message);
}

[Fact]
public void SingleKeyMustConvertToDictionary()
{
var sqlGenerator = new SqlGenerator<User>();

var id = new { Id = 1 };

var param = Assert.IsType<Dictionary<string, object>>(sqlGenerator.GetKeysParam(id));

var keyValue = Assert.Single(param);

Assert.Equal("Id", keyValue.Key);
Assert.Equal(id, keyValue.Value);
}

[Fact]
public void ArrayKeyValuesShouldConvertToDictionary()
{
var sqlGenerator = new SqlGenerator<Report>();

var param = Assert.IsAssignableFrom<IReadOnlyDictionary<string, object>>(sqlGenerator.GetKeysParam(new[] { 1, 2 }));

Assert.Equal(2, param.Count);

Assert.Equal(1, Assert.Contains("Id", param));
Assert.Equal(2, Assert.Contains("AnotherId", param));
}

[Fact]
public void ObjectKeyValuesShouldNotConvert()
{
var sqlGenerator = new SqlGenerator<Report>();

var id = new { Id = 1, AnotherId = 2 };

var param = sqlGenerator.GetKeysParam(id);

Assert.Equal(id, param);
}
}
}