mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 05:22:57 +01:00
Merge pull request #54 from radeanurazvan/master
Allowed configuring properties with identical name & type
This commit is contained in:
commit
d4b85b6bbc
@ -4,20 +4,19 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Sieve.Services
|
namespace Sieve.Services
|
||||||
{
|
{
|
||||||
public class SievePropertyMapper
|
public class SievePropertyMapper
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Type, Dictionary<PropertyInfo, ISievePropertyMetadata>> _map
|
private readonly Dictionary<Type, ICollection<KeyValuePair<PropertyInfo, ISievePropertyMetadata>>> _map
|
||||||
= new Dictionary<Type, Dictionary<PropertyInfo, ISievePropertyMetadata>>();
|
= new Dictionary<Type, ICollection<KeyValuePair<PropertyInfo, ISievePropertyMetadata>>>();
|
||||||
|
|
||||||
public PropertyFluentApi<TEntity> Property<TEntity>(Expression<Func<TEntity, object>> expression)
|
public PropertyFluentApi<TEntity> Property<TEntity>(Expression<Func<TEntity, object>> expression)
|
||||||
{
|
{
|
||||||
if(!_map.ContainsKey(typeof(TEntity)))
|
if(!_map.ContainsKey(typeof(TEntity)))
|
||||||
{
|
{
|
||||||
_map.Add(typeof(TEntity), new Dictionary<PropertyInfo, ISievePropertyMetadata>());
|
_map.Add(typeof(TEntity), new List<KeyValuePair<PropertyInfo, ISievePropertyMetadata>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PropertyFluentApi<TEntity>(this, expression);
|
return new PropertyFluentApi<TEntity>(this, expression);
|
||||||
@ -65,13 +64,16 @@ namespace Sieve.Services
|
|||||||
|
|
||||||
private void UpdateMap()
|
private void UpdateMap()
|
||||||
{
|
{
|
||||||
_sievePropertyMapper._map[typeof(TEntity)][_property] = new SievePropertyMetadata()
|
var metadata = new SievePropertyMetadata()
|
||||||
{
|
{
|
||||||
Name = _name,
|
Name = _name,
|
||||||
FullName = _fullName,
|
FullName = _fullName,
|
||||||
CanFilter = _canFilter,
|
CanFilter = _canFilter,
|
||||||
CanSort = _canSort
|
CanSort = _canSort
|
||||||
};
|
};
|
||||||
|
var pair = new KeyValuePair<PropertyInfo, ISievePropertyMetadata>(_property, metadata);
|
||||||
|
|
||||||
|
_sievePropertyMapper._map[typeof(TEntity)].Add(pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (string, PropertyInfo) GetPropertyInfo(Expression<Func<TEntity, object>> exp)
|
private static (string, PropertyInfo) GetPropertyInfo(Expression<Func<TEntity, object>> exp)
|
||||||
@ -105,8 +107,8 @@ namespace Sieve.Services
|
|||||||
var result = _map[typeof(TEntity)]
|
var result = _map[typeof(TEntity)]
|
||||||
.FirstOrDefault(kv =>
|
.FirstOrDefault(kv =>
|
||||||
kv.Value.Name.Equals(name, isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)
|
kv.Value.Name.Equals(name, isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)
|
||||||
&& (canSortRequired ? kv.Value.CanSort : true)
|
&& (!canSortRequired || kv.Value.CanSort)
|
||||||
&& (canFilterRequired ? kv.Value.CanFilter : true));
|
&& (!canFilterRequired || kv.Value.CanFilter));
|
||||||
|
|
||||||
return (result.Value?.FullName, result.Key);
|
return (result.Value?.FullName, result.Key);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Sieve.Attributes;
|
using Sieve.Attributes;
|
||||||
|
using SieveUnitTests.ValueObjects;
|
||||||
|
|
||||||
namespace SieveUnitTests.Entities
|
namespace SieveUnitTests.Entities
|
||||||
{
|
{
|
||||||
@ -7,6 +8,10 @@ namespace SieveUnitTests.Entities
|
|||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public Name AuthorFirstName { get; set; }
|
||||||
|
|
||||||
|
public Name AuthorLastName { get; set; }
|
||||||
|
|
||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ using Sieve.Models;
|
|||||||
using Sieve.Services;
|
using Sieve.Services;
|
||||||
using SieveUnitTests.Entities;
|
using SieveUnitTests.Entities;
|
||||||
using SieveUnitTests.Services;
|
using SieveUnitTests.Services;
|
||||||
|
using SieveUnitTests.ValueObjects;
|
||||||
|
|
||||||
namespace SieveUnitTests
|
namespace SieveUnitTests
|
||||||
{
|
{
|
||||||
@ -63,17 +64,23 @@ namespace SieveUnitTests
|
|||||||
new Comment() {
|
new Comment() {
|
||||||
Id = 0,
|
Id = 0,
|
||||||
DateCreated = DateTimeOffset.UtcNow.AddDays(-20),
|
DateCreated = DateTimeOffset.UtcNow.AddDays(-20),
|
||||||
Text = "This is an old comment."
|
Text = "This is an old comment.",
|
||||||
|
AuthorFirstName = new Name("FirstName1"),
|
||||||
|
AuthorLastName = new Name("LastName1")
|
||||||
},
|
},
|
||||||
new Comment() {
|
new Comment() {
|
||||||
Id = 1,
|
Id = 1,
|
||||||
DateCreated = DateTimeOffset.UtcNow.AddDays(-1),
|
DateCreated = DateTimeOffset.UtcNow.AddDays(-1),
|
||||||
Text = "This is a fairly new comment."
|
Text = "This is a fairly new comment.",
|
||||||
|
AuthorFirstName = new Name("FirstName2"),
|
||||||
|
AuthorLastName = new Name("LastName2")
|
||||||
},
|
},
|
||||||
new Comment() {
|
new Comment() {
|
||||||
Id = 2,
|
Id = 2,
|
||||||
DateCreated = DateTimeOffset.UtcNow,
|
DateCreated = DateTimeOffset.UtcNow,
|
||||||
Text = "This is a brand new comment. ()"
|
Text = "This is a brand new comment. ()",
|
||||||
|
AuthorFirstName = new Name("FirstName3"),
|
||||||
|
AuthorLastName = new Name("LastName3")
|
||||||
},
|
},
|
||||||
}.AsQueryable();
|
}.AsQueryable();
|
||||||
}
|
}
|
||||||
@ -365,5 +372,20 @@ namespace SieveUnitTests
|
|||||||
Assert.AreEqual(posts[2].Id, 2);
|
Assert.AreEqual(posts[2].Id, 2);
|
||||||
Assert.AreEqual(posts[3].Id, 1);
|
Assert.AreEqual(posts[3].Id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NestedFilteringWithIdenticTypesWorks()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "(firstName|lastName)@=*2",
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.Apply(model, _comments);
|
||||||
|
Assert.AreEqual(1, result.Count());
|
||||||
|
|
||||||
|
var comment = result.First();
|
||||||
|
Assert.AreEqual(comment.Id, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,14 @@ namespace SieveUnitTests.Services
|
|||||||
mapper.Property<Post>(p => p.OnlySortableViaFluentApi)
|
mapper.Property<Post>(p => p.OnlySortableViaFluentApi)
|
||||||
.CanSort();
|
.CanSort();
|
||||||
|
|
||||||
|
mapper.Property<Comment>(c => c.AuthorFirstName.Value)
|
||||||
|
.CanFilter()
|
||||||
|
.HasName("firstName");
|
||||||
|
|
||||||
|
mapper.Property<Comment>(c => c.AuthorLastName.Value)
|
||||||
|
.CanFilter()
|
||||||
|
.HasName("lastName");
|
||||||
|
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
SieveUnitTests/ValueObjects/Name.cs
Normal file
43
SieveUnitTests/ValueObjects/Name.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SieveUnitTests.ValueObjects
|
||||||
|
{
|
||||||
|
public sealed class Name : IEquatable<Name>
|
||||||
|
{
|
||||||
|
public Name(string value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid string!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.Length > 50)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("String exceeds maximum name length!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value { get; private set; }
|
||||||
|
|
||||||
|
public bool Equals(Name other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
return string.Equals(Value, other.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
|
return obj is Name && Equals((Name) obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (Value != null ? Value.GetHashCode() : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user