【发布时间】:2014-05-01 17:43:27
【问题描述】:
我正在使用 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()); }
}
【问题讨论】:
标签: c# linq entity-framework-5