gpt4 book ai didi

c# - 通过 LINQ 将表达式树应用于 List

转载 作者:行者123 更新时间:2023-12-03 01:11:41 25 4
gpt4 key购买 nike

我想为我的列表集合应用动态项目。用户将选择注意到但我的列表的属性的列。我想从 LINQ 语句获取列的子集。我想使用动态 LINQ。 any1能否提供如何用表达式树实现项目。我想在 Azure 表存储上应用动态投影..

我尝试实现下面的代码,它不起作用,它在读取属性时抛出异常:

Property XXXX is not defined for type 'System.String'

代码:

DataMovementDataContext dbMovement = new DataMovementDataContext();
var entity = dbMovement.ListofAccountingDocs2_1075s.AsQueryable();
Type type = entity.ElementType;
var entityParam = Expression.Parameter(entity.ElementType, "row");
Expression expr = entityParam;
string[] props = "AccountingDocumentNbr,GLCompanyCode,DocumentFiscalYearNbr".Split(',');
var epr = GenerateMemberExpression<ListofAccountingDocs2_1075, string>("Name");

foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
// type = pi.PropertyType; //Property 'System.String GLCompanyCode' is not defined for type 'System.String'
}

// row => row.Property
// var columnLambda = Expression.Lambda( Expression.Property(entityParam, "GLCompanyCode"), entityParam);
var columnLambda = Expression.Lambda(Expression.Property(expr, "AccountingDocumentNbr,GLCompanyCode"), entityParam);

// Items.Select(row => row.Property)
var selectCall = Expression.Call(typeof(Queryable), "Select", new Type[] { entity.ElementType, columnLambda.Body.Type }, entity.Expression, columnLambda);

// Items.Select(row => row.Property).Distinct
var distinctCall = Expression.Call(typeof(Queryable), "Distinct", new Type[] { typeof(string) }, selectCall);

// colvalue => colvalue
var sortParam = Expression.Parameter(typeof(string), "AccountingDocumentNbr");
var columnResultLambda = Expression.Lambda(sortParam, sortParam);

// Items.Select(row => row.Property).Distinct.OrderBy(colvalue => colvalue)
var ordercall = Expression.Call(typeof(Queryable), "OrderBy",
new Type[] { typeof(string), columnResultLambda.Body.Type },
distinctCall, columnResultLambda);

var result = entity.Provider.CreateQuery(ordercall);
foreach (var item in result)
{
Console.Write(item);
}

最佳答案

如果您发布您正在使用的模型的类定义,事情会容易得多。

但是,您似乎正在尝试通过链接来获取多个属性。这是行不通的。我想你想要的是:

  new { 
AccountingDocumentNbr = document.AccountingDocumentNbr,
GLCompanyCode = document.GLCompanyCode ,
DocumentFiscalYearNbr = document.DocumentFiscalYearNbr
};

但是 foreach (props 中的 string prop) 循环实际上是您需要的,以便为您提供:

  document.AccountingDocumentNbr.GLCompanyCode.DocumentFiscalYearNbr

现在,它看起来像 document.AccountingDocumentNbr 是一个 string,因为您得到 Property 'System.String GLCompanyCode' is not Define for type ' System.String' 错误。当您像这样查看它时,错误是有道理的... System.String 没有 GLCompanyCode 属性,并且您正在构建一个期望的链式属性表达式它拥有一个。还会发生什么?

您将无法获取您所定位的匿名对象,除非您的解决方案中已存在该类型的实例。这是因为匿名类型不是动态类型。它们可能看起来像这样,但实际上是 internal types compiled into the assembly ,并且它们的功能与具有相同成员和自定义重写 Equals(object obj)GetHashCode()ToString 的任何其他类没有任何不同()。因此,除非您有办法引用具有您正在查找的定义的类,否则您将无法使用反射访问这些成员(因为它们不存在)。只使用 lambda 表达式会更好。

为了更清楚一点,下面是上面匿名类型的类定义的样子(差不多)。

public class <>f__AnonymousType0<T1,T2,T3>
{
private readonly T1 accountingDocumentNbr;
private readonly T2 glCompanyCode;
private readonly T3 documentFiscalYearNbr;

public T1 AccountingDocumentNbr
{
get { return accountingDocumentNbr; }
}

public T2 GLCompanyCode
{
get { return glCompanyCode; }
}

public T3 DocumentFiscalYearNbr
{
get { return documentFiscalYearNbr; }
}

public <>f__AnonymousType0(T1 accountingDocumentNbr, T2 glCompanyCode, T3 documentFiscalYearNbr)
{
this.accountingDocumentNbr = accountingDocumentNbr;
this.glCompanyCode = glCompanyCode;
this.documentFiscalYearNbr = documentFiscalYearNbr;
}

public override string ToString()
{
var builder = new StringBuilder();
builder.Append("{ AccountingDocumentNbr = ");
builder.Append(AccountingDocumentNbr);
builder.Append(", GLCompanyCode = ");
builder.Append(GLCompanyCode);
builder.Append(", DocumentFiscalYearNbr = ");
builder.Append(DocumentFiscalYearNbr);
builder.Append(" }");
return builder.ToString();
}

public override bool Equals(object value)
{
var type = value as <>f__AnonymousType0<T1,T2,T3>;
return (type != null) && EqualityComparer<T1>.Default.Equals(type.AccountingDocumentNbr, AccountingDocumentNbr) && EqualityComparer<T2>.Default.Equals(type.GLCompanyCode, GLCompanyCode) && EqualityComparer<T3>.Default.Equals(type.DocumentFiscalYearNbr, DocumentFiscalYearNbr);
}

public override int GetHashCode()
{
int num = 0x7a2f0b42;
num = (-1521134295*num) + EqualityComparer<T1>.Default.GetHashCode(AccountingDocumentNbr);
num = (-1521134295*num) + EqualityComparer<T2>.Default.GetHashCode(GLCompanyCode);
return (-1521134295*num) + EqualityComparer<T3>.Default.GetHashCode(DocumentFiscalYearNbr);
}
}

关于c# - 通过 LINQ 将表达式树应用于 List,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com