diff --git a/src/AutoFilterer/Types/StringFilter.cs b/src/AutoFilterer/Types/StringFilter.cs
index 91f59a4..1889c25 100644
--- a/src/AutoFilterer/Types/StringFilter.cs
+++ b/src/AutoFilterer/Types/StringFilter.cs
@@ -66,6 +66,16 @@ public class StringFilter : IFilterableType
/// Provides parameter to check is not null.
///
public virtual bool? IsNotNull { get; set; }
+
+ ///
+ /// Provides parameter to check is empty string.
+ ///
+ public virtual bool? IsEmpty { get; set; }
+
+ ///
+ /// Provides parameter to check is not empty string.
+ ///
+ public virtual bool? IsNotEmpty { get; set; }
///
///
@@ -114,6 +124,31 @@ public virtual Expression BuildExpression(Expression expressionBody, PropertyInf
if (NotEndsWith != null)
expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.EndsWith) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, NotEndsWith)), CombineWith);
+
+ if (IsEmpty != null)
+ {
+ if (IsEmpty.Value)
+ {
+ expression = expression.Combine(new StringFilterOptionsAttribute(StringFilterOption.Equals) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, ""), CombineWith);
+ }
+ else
+ {
+ expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.Equals) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, "")), CombineWith);
+ }
+ }
+
+ if (IsNotEmpty != null)
+ {
+ if (IsNotEmpty.Value)
+ {
+ expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.Equals) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, "")), CombineWith);
+ }
+ else
+ {
+ expression = expression.Combine(new StringFilterOptionsAttribute(StringFilterOption.Equals) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, ""), CombineWith);
+ }
+ }
+
return expression;
}
}
diff --git a/tests/AutoFilterer.Tests/Types/StringFilterTests.cs b/tests/AutoFilterer.Tests/Types/StringFilterTests.cs
index 44ccfd8..f48ba47 100644
--- a/tests/AutoFilterer.Tests/Types/StringFilterTests.cs
+++ b/tests/AutoFilterer.Tests/Types/StringFilterTests.cs
@@ -171,4 +171,66 @@ public void BuildExpression_TitleWithIsNotNull_ShouldMatchCount(List data)
foreach (var item in actualResult)
Assert.Contains(item, result);
}
+
+ [Theory, AutoMoqData(count: 64)]
+ public void BuildExpression_TitleWithIsEmpty_ShouldMatchCount(List data)
+ {
+ for (var i = 0; i < 5; i++)
+ {
+ data[i].Title = "";
+ }
+
+ // Arrange
+ var filter = new BookFilter_StringFilter_Title
+ {
+ Title = new StringFilter
+ {
+ IsEmpty = true
+ }
+ };
+
+ // Act
+ var query = data.AsQueryable().ApplyFilter(filter);
+ var result = query.ToList();
+
+ // Assert
+ var actualResult = data.AsQueryable().Where(x => x.Title == "").ToList();
+
+ Assert.Equal(actualResult.Count, result.Count);
+ Assert.Equal(5, actualResult.Count);
+ Assert.Equal(5, result.Count);
+ foreach (var item in actualResult)
+ Assert.Contains(item, result);
+ }
+
+ [Theory, AutoMoqData(count: 64)]
+ public void BuildExpression_TitleWithIsNotEmpty_ShouldMatchCount(List data)
+ {
+ for (var i = 0; i < 5; i++)
+ {
+ data[i].Title = "";
+ }
+
+ // Arrange
+ var filter = new BookFilter_StringFilter_Title
+ {
+ Title = new StringFilter
+ {
+ IsNotEmpty = true
+ }
+ };
+
+ // Act
+ var query = data.AsQueryable().ApplyFilter(filter);
+ var result = query.ToList();
+
+ // Assert
+ var actualResult = data.AsQueryable().Where(x => x.Title != "").ToList();
+
+ Assert.Equal(actualResult.Count, result.Count);
+ Assert.Equal(64 - 5, actualResult.Count);
+ Assert.Equal(64 - 5, result.Count);
+ foreach (var item in actualResult)
+ Assert.Contains(item, result);
+ }
}