簡體   English   中英

如何使用實體框架管理的類的屬性創建動態過濾器?

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

我正在使用 Entity Framework 6 開發應用程序,但我無法使用 Entity Framework 管理的實體類的屬性來解決動態過濾器的問題。

問題實際上是類的不可為空的屬性(可以與空值進行比較)。

背景

我正在使用傳統框架將應用程序分成 3 個項目(模型、視圖、控制器)和 C#。

使用 SQL Server 2017 作為數據庫和實體框架(不是核心)。

我試過的

我做了幾次谷歌查詢,但沒有一個解決我的問題。

最接近解決方案的答案是這里的Entity Framework Core - 動態過濾用戶 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().Retrieve();
// Dynamic query here!

編輯

我試過這個,但它不起作用:

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

預期的:

主要思想是使查詢靈活,以便最終用戶可以通過實體類的任何屬性過濾數據。

例如:用戶選擇名稱或包名稱的一部分並且不指示記錄是否處於活動狀態,考慮到上述查詢,只會通知 Name 屬性,Active 屬性將接收空值,查詢將返回所有值,其中包名稱是用戶選擇的值,無論它是活動的還是停用的。

實際結果

由於我不能調整動態過濾器,那么如果用戶通知包的“名稱”屬性或“名稱”的一部分,並且沒有說明它是否處於活動狀態,.NET會自動初始化“活動”的值" 包的屬性為 false,這最終會返回所有禁用的包,其名稱或名稱的一部分由用戶選擇。

使屬性Active 可以為空(因此它匹配數據庫中的字段類型),它將解決您的問題。

實體類:

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

非常感謝您的觀看和回復。

經過一些測試和 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; }
}

到目前為止,好吧,我需要以某種方式使用我的查詢機制,並且我能夠通過調用稱為過程的實體框架並使用可為空參數來做到這一點,最終結果是這樣的:

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>();
    }
}

我運行了幾次測試,在那種情況下,查詢 100% 靈活滿足我的需求。

我真的希望這項努力可以幫助社區中的某個人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM