是否有辦法對 Entity Framework DBSets 執行 LINQ 查詢并僅回傳具有特定自定義屬性的屬性?
我的目標是執行查詢并僅回傳我在匯出時需要的屬性/列。
我還希望將其作為 IEnumerable 的擴展,因為我有許多單獨的 EF 類將使用該匯出屬性。
我是這樣設想的:
我是這樣設想的:
public class Person
{
出口] [出口]
public string FirstName { get; set; }
[出口]
public string LastName { get; set; }
[出口]
public string Address { get; set; }
[NeverExport]。
public string SocialSecurityNumber { get; set; }
}
public void main()
{
var people = PersonRepository.GetAll()。
var exportResults = people.GetByAttribute(ExportAttribute)。
{
public static IEnumerable<object> GetByAttribute(thisIEnumerable<object> list, Attribute attribute)。
{
return list
.Select(x =>
//選擇帶有{ attribute }的屬性。(即[出口])
);
uj5u.com熱心網友回復:
我為你的問題做了一個非常基本的例子。簡而言之,你想獲得所有的屬性,其中有一個特定的Attribute存在。你可以通過反射來實作這一點。首先,你想獲得特定型別的所有屬性,然后只獲得特定屬性存在的屬性。
下面是我的示例代碼:
using System;
using System.Linq;
using System.Reflection;
namespace Sandbox
{
public class Program {
{
public static void Main(string[] args)
{
var attrs = typeof(User).GetProperties().Where(x => x.GetCustomAttributes().Any(y => y.GetType() == typeof(Custom) )。)
var users = new User[] 。
{
new User() { ID = 1, Name = "John" , Lastname = "Doe" },
new User() { ID = 2, Name = "Jane", Lastname = "Doe" }.
};
foreach(var u in users)
{
foreach(var attr in attrs)
{
Console.WriteLine(typeof(User).GetProperty(attr.Name).GetValue(u, null))。
}
}
}
}
public class Userpublic string Name { get; set; }
[] 。
public int ID { get; set; }
[] 。
public string Lastname { get; set; }
}
public class Custom : System.Attribute
{
}
}
uj5u.com熱心網友回復:
下面的代碼將任何IQueryable投影到IQueryable<ExpandoObject>,你可以用它來匯出資料。此外,代碼還快取了投影運算式,以便以后在應用程式中重復使用。
使用方法很簡單:
var exportResult = anyQuery.ProjectForExport().ToList() 。
和實作:
[AttributeUsage(AttributeTargets.Property)]
public class ExportAttribute : Attribute
{
}
public static class ExportTools
{
private static readonly ConstructorInfo _expandoObjectConstructor =
typeof(ExpandoObject).GetConstructor(Type.EmptyTypes)? throw new InvalidOperationException();
private static readonly MethodInfo _expandoAddMethodInfo = typeof(IDictionary< string, object>)。) .GetTypeInfo()
.GetRuntimeMethods()
.Single(mi => mi.Name == nameof(IDictionary<string, object> 。 Add) && mi.GetParameters().Length == 2)。)
public static class ProjectionCache<T>
{
public static Expression<Func<T, ExpandoObject>> ProjectionExpression { get; } = BuildProjection()。
private static Expression<Func<T, ExpandoObject> > BuildProjection()
{
var param = Expression.Parameter(typeof(T), "e") 。
var properties = typeof(T).GetProperties()
.Where(p => p.GetCustomAttributes().Any(a => a is ExportAttribute)).ToList()。
if (properties.Count == 0)
throw new InvalidOperationException($"Type '{typeof(T) 。 Name}'沒有定義出口屬性。")。)
var expr = (Expression)Expression.ListInit(
Expression.New(_expandoObjectConstructor),
properties.Select(p =>
{
var readerExpr = Expression.MakeMemberAccess(param, p);
return Expression.ElementInit(_expandoAddMethodInfo, Expression.Constant(p.Name), readerExpr) 。
}));
var lambda = Expression.Lambda<Func<T, ExpandoObject>>(expr, param)。
return lambda;
}
}
public static IQueryable<ExpandoObject> ProjectForExport<T>(this IQueryable<T> query)
{
return query.Select(ProjectionCache<T>.ProjectionExpression)。
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/310116.html
標籤:
上一篇:如何用groupby和orderby來LINQDataTable,以消除資料的重復性
下一篇:如何在安卓串列視圖中添加大量資料
