gpt4 book ai didi

c# - 使用 Linq 表达式计算的属性

转载 作者:太空宇宙 更新时间:2023-11-03 10:45:56 25 4
gpt4 key购买 nike

我正在使用 LINQ to Entities (EF5) 从现有数据库中获取和筛选产品列表。产品的价格可能或可能没有折扣(统一费率或百分比)。我希望在服务器端进行计算,以便我可以轻松地进行过滤、排序和检索折扣价,而无需编写大量重复的 Linq,并在顶部再重新计算一些客户端代码。

我知道 Linq 不能神奇地将客户端函数转换为 SQL,但据我所知,我可以编写一个表达式可以翻译成 SQL。看来我应该能够编写一个表达式并将该值存储为一个“列”。

我已经看到一些示例似乎可以满足我的要求:

http://blog.cincura.net/230786-using-custom-properties-as-parameters-in-queries-in-ef/

Include derived property into a linq to entity query

问题是,我无法让表达式/属性在基本级别上发挥作用。暂时忘记折扣计算...

下面,如果产品 ID 大于 3,我有一个简单的表达式来评估为“真”。我有一个属性返回表达式结果的产品模型。当我尝试获取该属性时,我得到一个 NotSupportedException:“LINQ to Entities 不支持指定的类型成员‘test’。只有初始化程序、实体成员和实体导航支持属性。”

public partial class ProductList
{
protected void Page_Load(object sender, EventArgs e)
{
using (var db = new eTailerContext())
{
var products = db.products
.Select(p => new
{
id = p.id,
name = p.name,
mytest = p.test
});
}
}
}

public class Product
{
public id { get; set; }
public name { get; set; }

public bool test
{
get { return testExpression.Compile()(this); }
}

public static Expression<Func<Product, bool>> testExpression
{
get { return t => t.id > 3; }
}
}

或者,我试过

mytest = Product.testExpression.Compile()(p)

但这会引发不同的 NotSupported 异常:“LINQ to Entities 不支持 LINQ 表达式节点类型‘Invoke’。”真的没有办法吗?这似乎是一个非常普遍的需求。

配置代码如下:

public class ProductMap : EntityTypeConfiguration<Product>
{
public ProductMap()
{
this.HasKey(t => t.id);
this.ToTable("Products");
this.Property(t => t.id).HasColumnName("ProductID");
this.Property(t => t.name).HasColumnName("ProductName").HasMaxLength(255);

this.Ignore(t => t.test);
}
}

public class MyDbContext : DbContext
{
public DbSet<Product> products { get; set; }

public MyDbContext() : base("Name=SiteSqlServer")
{ }

static MyDbContext()
{
Database.SetInitializer<MyDbContext>(null);
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ modelBuilder.Configurations.Add(new ProductMap()); }
}

最佳答案

您需要将整个选择包装成一个表达式。

public class Product
{
public int id { get; set; }
public string name { get; set; }

public bool test
{
get { return id > 3;}
}

public static Expression<Func<Product, dynamic>> TestExpression =
p => new
{
id = p.id,
name = p.name,
mytest = p.id > 3
};
}

然后就可以使用了

var products = db.products
.Select(Product.TestExpression);

这将产生和类似的 SQL 语句

SELECT 
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
CASE WHEN ([Extent1].[ProductID] > 3) THEN cast(1 as bit) WHEN ( NOT ([Extent1].[ProductID] > 3)) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[Products] AS [Extent1]

注意:您可能应该使用真实类而不是动态类

关于c# - 使用 Linq 表达式计算的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23413296/

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