简体   繁体   English

如何使用实体框架管理的类的属性创建动态过滤器?

[英]How to create a dynamic filter using the attributes of a class managed by the Entity Framework?

I'm developing an application using Entity Framework 6, and I'm not able to resolve the issue of dynamic filters using the properties of an entity class managed by Entity Framework.我正在使用 Entity Framework 6 开发应用程序,但我无法使用 Entity Framework 管理的实体类的属性来解决动态过滤器的问题。

The problem in fact is the non-nullable properties (which can be compared to null) of the class.问题实际上是类的不可为空的属性(可以与空值进行比较)。

Background背景

I'm using a conventional framework separating the application into 3 projects (Model, View, Controller) with C#.我正在使用传统框架将应用程序分成 3 个项目(模型、视图、控制器)和 C#。

Using SQL Server 2017 as a database and Entity Framework (not the Core).使用 SQL Server 2017 作为数据库和实体框架(不是核心)。

What I have tried我试过的

I did several Google queries but none of them approached my problem.我做了几次谷歌查询,但没有一个解决我的问题。

The answer that most approached the solution was this here Entity Framework Core - dynamic filtering user Marcio Martins, but I did not see anything about how to handle non-nullable properties .最接近解决方案的答案是这里的Entity Framework Core - 动态过滤用户 Marcio Martins,但我没有看到有关如何处理不可为空属性的任何信息。

Would anyone have an idea how to fix this?有谁知道如何解决这个问题?

Code代码

I need to see a way to translate the query below into a lambda or linq expression:我需要找到一种方法将下面的查询转换为 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)

The entity class实体类

public class Package
{
    [Key]
    public Int32 PackageID { get; set; }
    [Required]
    [MaxLength(20)]
    public String Name { get; set; }
    public Boolean Active { get; set; }
}

The snippet code from View. View 中的片段代码。

List<Package> packages = new PackageController().Retrieve();
// Dynamic query here!

EDIT编辑

I tried this, but it was not functional:我试过这个,但它不起作用:

List<Package> packages = new PackageController().Retrieve()
                                                .Where(p =>  String.IsNullOrEmpty(p.Name) || p.Name.Contains(package.Name))
                                                .ToList();

Expected:预期的:

The main idea is to make the query flexible so that the end user can filter the data by any of the properties of the entity class.主要思想是使查询灵活,以便最终用户可以通过实体类的任何属性过滤数据。

Ex: the user selects the name or part of the package name and DOES NOT indicate whether the records are active or not, considering the above query, only the Name attribute would be informed, the Active attribute would receive the null value, and the query would return all the values where Package Name is the one selected by the user regardless if it is active or deactivated.例如:用户选择名称或包名称的一部分并且不指示记录是否处于活动状态,考虑到上述查询,只会通知 Name 属性,Active 属性将接收空值,查询将返回所有值,其中包名称是用户选择的值,无论它是活动的还是停用的。

Actual results实际结果

As I can not adjust the dynamic filter, then if the user informs the "Name" property of the package or part of the "Name" and does not say whether it is active or not, .NET automatically initializes the value of the "Active" property of the Package to false, and this ends up returning all disabled Packages with the name or part of the name selected by the user.由于我不能调整动态过滤器,那么如果用户通知包的“名称”属性或“名称”的一部分,并且没有说明它是否处于活动状态,.NET会自动初始化“活动”的值" 包的属性为 false,这最终会返回所有禁用的包,其名称或名称的一部分由用户选择。

Make property Active nullable (so it matches the field type in the database) and it will solve your problem.使属性Active 可以为空(因此它匹配数据库中的字段类型),它将解决您的问题。

Entity class:实体类:

public class Package
{
    ...
    public Boolean? Active { get; set; }
}

Thank you so much for seeing and responding.非常感谢您的观看和回复。

I was able to SOLVE THE PROBLEM after some tests and an idea that Przemek Marcinkiewicz gave me in his answer.经过一些测试和 Przemek Marcinkiewicz 在他的回答中给我的想法,我能够解决问题

Come on, this answer can help many in the future.来吧,这个答案可以在未来帮助很多人。

I needed to make the properties of the Package class be nullable, but without changing the bank model, I did this by configuring the class like this:我需要使 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; }
}

So far, okay, with this I needed to somehow use the mechanism of my query, and I was able to do it by calling the Entity framework called the procedure and with nullable parameters, the final result was like this:到目前为止,好吧,我需要以某种方式使用我的查询机制,并且我能够通过调用称为过程的实体框架并使用可为空参数来做到这一点,最终结果是这样的:

public List<Package> Retrieve(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>();
    }
}

I ran several tests, and in that case the query was 100% flexible for my needs.我运行了几次测试,在那种情况下,查询 100% 灵活满足我的需求。

I really hope this effort can help someone in the community.我真的希望这项努力可以帮助社区中的某个人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有实体框架的动态自定义属性 - Dynamic Custom Attributes with Entity Framework 如何创建像Expression这样的动态实体框架过滤器表达式 <Func<T, bool> &gt; - How to create dynamic entity framework filter expression like Expression<Func<T, bool>> 将Entity Framework与“动态”实体一起使用? - Using Entity Framework with “dynamic” entity? 实体框架-如何为实体类创建基类? - Entity Framework - How to create base class for entity class? 如何在实体框架核心中制作动态查询过滤器? - How can I make a dynamic query filter in entity framework core? 使用Entity Framework 4如何过滤引用的实体集合 - Using Entity Framework 4 how to filter referenced Entity Collection 如何创建一个从实体对象继承的类??? (实体框架) - How to create a class that inherits from an entity object??? (Entity Framework) 如何使用 Entity Framework Core 在 ASP.NET Core 中创建动态 select 框? - How to create dynamic select box in ASP.NET Core using Entity Framework Core? 在MVC Razor中使用实体框架创建动态列表 - Create a Dynamic List using Entity Framework in MVC Razor 如何使用Entity Framework和Linq创建此查询 - How to create this query using Entity Framework and Linq
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM