Dynamic LINQ
Dynamic LINQ is FREE and always will be. However, last year alone, we spent over 3000 hours maintaining our free projects! We need resources to keep developing our open-source projects. We highly appreciate any contribution!
dynamic-linq.net
dynamic linq 는 동적 쿼리를 동적 문자열로 처리할 수 있도록 해줍니다.
아래처럼 Linq 식을 보통 사용하게 되지만
var result = context.Customers
.Where(c => c.City == "Paris")
.ToList();
dynamic linq 를 이용하면 아래처럼 사용할 수 있습니다.
var resultDynamic = context.Customers
.Where("City == \"Paris\"")
.ToList();
사용하기 위해선 System.Linq.Dynamic.Core Nuget package 를 설치합니다.
아래는 TestData Class 를 정의하여 사용하는 방법의 예시입니다.
public class TestData
{
public string Name { get; set; }
public int Age { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public int intData1 { get; set; }
public int intData2 { get; set; }
}
List<TestData> testDataList = new List<TestData>();
// 사용 예시
var queryableData = testDataList.AsQueryable();
var where = queryableData.Where("Name == @0", "NAME0").ToList();
var avg = queryableData.Aggregate("Average", "intData1");
var and = queryableData.Where("Name == @0 and intData1 > @1", "NAME0", 3).ToList();
var select = queryableData.Select("new { Name, Data1 }").ToDynamicList();
var orderedDynamic = queryableData.OrderBy("Name, intData2").ToList();
동적 문자열로 쿼리가 가능해 다양한 조합의 쿼리식을 처리할 수 있습니다.
GroupBy 도 아래처럼 처리할 수 있습니다.
List<dynamic> testDynamicList = new List<dynamic>();
var queryableData = testDynamicList.AsQueryable();
// 싱글 컬럼 GroupBy
var onColumnGroups = queryableData.GroupBy("Name");
foreach (IGrouping<object, object> group in onColumnGroups)
{
string Key = group.Key.ToString();
var dataList = group.ToList();
Console.WriteLine($"{Key} : {dataList.Count()}");
}
// 멀티 컬럼 GroupBy
var multiColumnGroups = queryableData.GroupBy("new (Name as Name, Data1 as Data1)");
foreach (IGrouping<object, object> group in multiColumnGroups)
{
string Key = group.Key.ToString();
var dataList = group.ToList();
Console.WriteLine($"{Key} : {dataList.Count()}");
}
// 멀티 컬럼 GroupBy + 키값 및 키별 Count
var gResult = queryableData.GroupBy("new (Name as Name, Data1 as Data1)").Select("new(Key, Count() AS Count)");
foreach (dynamic result in gResult)
{
Console.WriteLine($"{result.Key} : {result.Count}");
}
// 멀티 컬럼 GroupBy + 특정 컬럼만 선택
var multiColumnGroupsResult = queryableData.GroupBy("new (Name as Name, Data1 as Data1)", "new (Data2 as Data2, intData2 as intData2)");
foreach (IGrouping<object, object> group in multiColumnGroupsResult)
{
Console.WriteLine($"{group.Key} : {group.Count()}");
}
또한 DynamicClass 를 정의하여 사용할 수도 있습니다.
DynamicProperty[] props = new DynamicProperty[]
{
new DynamicProperty("Name", typeof(string)),
new DynamicProperty("Birthday", typeof(DateTime))
};
Type type = DynamicClassFactory.CreateType(props);
object obj = Activator.CreateInstance(type);
type.GetProperty("Name").SetValue(obj, "kei", null);
type.GetProperty("Birthday").SetValue(obj, new DateTime(1995, 3, 14), null);
Console.WriteLine(obj);
전체 코드
using System.Linq.Dynamic.Core;
namespace DynamicLinqTest
{
internal class Program
{
List<dynamic> testDynamicList = new List<dynamic>();
List<TestData> testDataList = new List<TestData>();
static void Main(string[] args)
{
Program program = new Program();
program.SampleData(100);
program.DynamicClass();
program.BasicQuery();
program.GroupBy();
program.Expression();
}
private void SampleData(int count)
{
for (int i = 0; i < count; i++)
{
TestData testData = new TestData()
{
Name = "NAME" + (i / 10),
Age = i,
Data1 = "Data1_" + (i / 5),
Data2 = "Data2_" + i,
intData1 = i + 1,
intData2 = count - i,
};
testDynamicList.Add(testData);
testDataList.Add(testData);
}
}
private void DynamicClass()
{
DynamicProperty[] props = new DynamicProperty[]
{
new DynamicProperty("Name", typeof(string)),
new DynamicProperty("Birthday", typeof(DateTime))
};
Type type = DynamicClassFactory.CreateType(props);
object obj = Activator.CreateInstance(type);
type.GetProperty("Name").SetValue(obj, "kei", null);
type.GetProperty("Birthday").SetValue(obj, new DateTime(1995, 3, 14), null);
Console.WriteLine(obj);
}
private void BasicQuery()
{
var queryableData = testDataList.AsQueryable();
var where = queryableData.Where("Name == @0", "NAME0").ToList();
var avg = queryableData.Aggregate("Average", "intData1");
var and = queryableData.Where("Name == @0 and intData1 > @1", "NAME0", 3).ToList();
var select = queryableData.Select("new { Name, Data1 }").ToDynamicList();
var orderedDynamic = queryableData.OrderBy("Name, intData2").ToList();
}
private void GroupBy()
{
var queryableData = testDynamicList.AsQueryable();
// 싱글 컬럼 GroupBy
var onColumnGroups = queryableData.GroupBy("Name");
foreach (IGrouping<object, object> group in onColumnGroups)
{
string Key = group.Key.ToString();
var dataList = group.ToList();
Console.WriteLine($"{Key} : {dataList.Count()}");
}
// 멀티 컬럼 GroupBy
var multiColumnGroups = queryableData.GroupBy("new (Name as Name, Data1 as Data1)");
foreach (IGrouping<object, object> group in multiColumnGroups)
{
string Key = group.Key.ToString();
var dataList = group.ToList();
Console.WriteLine($"{Key} : {dataList.Count()}");
}
// 멀티 컬럼 GroupBy + 키값 및 키별 Count
var gResult = queryableData.GroupBy("new (Name as Name, Data1 as Data1)").Select("new(Key, Count() AS Count)");
foreach (dynamic result in gResult)
{
Console.WriteLine($"{result.Key} : {result.Count}");
}
// 멀티 컬럼 GroupBy + 특정 컬럼만 선택
var multiColumnGroupsResult = queryableData.GroupBy("new (Name as Name, Data1 as Data1)", "new (Data2 as Data2, intData2 as intData2)");
foreach (IGrouping<object, object> group in multiColumnGroupsResult)
{
Console.WriteLine($"{group.Key} : {group.Count()}");
}
}
private void Expression()
{
var rangeOfNumbers = Enumerable.Range(1, 100).ToArray();
var result1 = rangeOfNumbers.AsQueryable().Where("it in (1,3,5,7, 101)").ToArray();
var values = new int[] { 2, 4, 6, 8, 102 };
var result2 = rangeOfNumbers.AsQueryable().Where("it in @0", values).ToArray();
var result3 = rangeOfNumbers.AsQueryable().Where("it % 2 = 0");
var result4 = rangeOfNumbers.AsQueryable().Select("it % 2 == 0 ? true : false");
}
public class TestData
{
public string Name { get; set; }
public int Age { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public int intData1 { get; set; }
public int intData2 { get; set; }
}
}
}
C# RadzenButton ToolTip / Busy indicator 표시하기 (0) | 2024.03.30 |
---|---|
C# Balzor Page 에서 NavMenu 로 데이터 전달하기 (0) | 2024.03.23 |
C# DataSet ReadXML 오류 '경로에 잘못된 문자가 있습니다.' (0) | 2024.03.13 |
C# DataTable은 Xml에서 스키마 유추를 지원하지 않습니다. (0) | 2024.03.13 |
C# MemoryPack (0) | 2024.03.06 |