我正在使用Entity Framework 6开发应用程序,但无法使用Entity Framework管理的实体类的属性解决动态过滤器的问题。
问题实际上是该类的不可为空的属性(可以将其与null进行比较)。
背景
我正在使用常规框架,使用C#将应用程序分为3个项目(模型,视图,控制器)。
使用SQL Server 2017作为数据库和实体框架(不是Core)。
我尝试过的事情
我做了几个Google查询,但没有一个能解决我的问题。
最接近解决方案的答案是Entity Framework Core - dynamic filtering用户Marcio Martins,但是我对如何处理非空属性一无所知。
会有人知道如何解决此问题吗?
代码
我需要找到一种将以下查询转换为lambda或linq表达式的方法:
-- Sql Server query
declare @ProductID int
declare @Name nvarchar(600)
declare @BarCode nvarchar(26)
declare @Active bit
declare @Price decimal
select
p.ProductID
, p.Name
, p.BarCode
, p.Active
, p.Price
from
Product p
where
(@ProductID is null or p.ProductID = @ProductID)
and (@Name is null or p.Name = @Name)
and (@BarCode is null or p.BarCode = @BarCode)
and (@Active is null or p.Active = @Active)
and (@Price is null or p.Price = @Price)
实体类
public class Package
{
[Key]
public Int32 PackageID { get; set; }
[Required]
[MaxLength(20)]
public String Name { get; set; }
public Boolean Active { get; set; }
}
View中的代码段。
List<Package> packages = new PackageController().Retreave();
// Dynamic query here!
编辑
我尝试了这个,但是没有用:
List<Package> packages = new PackageController().Retrieve()
.Where(p => String.IsNullOrEmpty(p.Name) || p.Name.Contains(package.Name))
.ToList();
预期:
主要思想是使查询变得灵活,以便最终用户可以通过实体类的任何属性来过滤数据。
Ex:用户选择包名的名称或一部分,并且不指示记录是否处于活动状态,考虑到上述查询,仅会通知Name属性,Active属性将接收空值,并且查询将返回“包名称”是用户选择的“包名称”之一的所有值,无论它是处于活动状态还是已停用。
实际结果
由于我无法调整动态过滤器,因此,如果用户通知程序包的“名称”属性或“名称”的一部分而没有说出它是否处于活动状态,则.NET会自动初始化的值。将Package的“ Active”属性设置为false,这最终将返回所有禁用的Package,其名称或用户选择的名称的一部分。
答案 0 :(得分:0)
使属性 Active 可为空(因此与数据库中的字段类型匹配),它将解决您的问题。
实体类:
public class Package
{
...
public Boolean? Active { get; set; }
}
答案 1 :(得分:0)
非常感谢您的看到和回应。 经过一些测试以及Przemek Marcinkiewicz回答我的想法,我得以解决问题。 来吧,这个答案可以在将来帮助很多人。 我需要使Package类的属性为可空的,但是在不更改库模型的情况下,我是通过这样配置类来做到这一点的:
public class Package
{
[Key]
[Required]
public Int32? PackageID { get; set; }
[Required]
[MaxLength(20)]
public String Name { get; set; }
[Required]
public Boolean Active? { get; set; }
}
到目前为止,好的,我需要以某种方式使用查询机制,并且能够通过调用称为过程的Entity框架并使用可为空的参数来做到这一点,最终结果是这样的:>
public List<Package> Retreave(Package entity)
{
using (MyDatabaseContext db = new MyDatabaseContext())
{
return db.Database
.SqlQuery<Package>
(
"PROC_PACKAGE_SELECT @PackageID, @Name, @Active"
, new SqlParameter("@PackageID", (object)entity.PackageID ?? DBNull.Value)
, new SqlParameter("@Name", (object)entity.Name ?? DBNull.Value)
, new SqlParameter("@Active", (object)entity.Active ?? DBNull.Value)
)
.ToList<Package>();
}
}
我进行了几次测试,在这种情况下,查询可以100%灵活地满足我的需求。
我真的希望这项工作可以为社区中的某人提供帮助。