Как создать динамический фильтр, используя атрибуты класса, управляемого Entity Framework? - PullRequest
0 голосов
/ 11 июля 2019

Я занимаюсь разработкой приложения с использованием Entity Framework 6 и не могу решить проблему с динамическими фильтрами, используя свойства класса сущностей, управляемого Entity Framework.

Фактически проблема заключается в том, чтонеобнуляемые свойства (которые можно сравнить с нулем) класса.

Фон

Я использую обычную структуру, разделяющую приложение на 3 проекта (Модель, представление, контроллер) с C #.

Использование SQL Server 2017 в качестве базы данных и Entity Framework (не ядра).

То, что я пробовал

Я сделал несколько запросов Google, но ни один из них не подошел к моей проблеме.

Ответ, который больше всего подходил к решению, был следующим: Entity Framework Core - динамическая фильтрация пользователь Марсио Мартинс, но яничего не видел о том, как обрабатывать ненулевые свойства.

У кого-нибудь есть идеи, как это исправить?

Код

Мне нужночтобы увидеть путьчтобы перевести запрос ниже в лямбда-выражение или выражение 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!

EDIT

Я пробовал это, но это не работало:

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

Ожидается:

Основная идея состоит в том, чтобы сделать запрос гибким, чтобыконечный пользователь может фильтровать данные по любому из свойств класса сущности.

Пример: пользователь выбирает имя или часть имени пакета и НЕ указывает, активны ли записи или нет, учитывая вышеизложенное.запрос, только атрибут Name будет проинформирован, атрибут Active получит нулевое значение, и запрос будет возвращать все значения, где имя пакета является тем, которое выбрано пользователем, независимо от того, активно оно или деактивировано.

Фактические результаты

Поскольку я не могу настроить динамический фильтр, то если пользователь сообщает свойству «Имя» пакета или части «Имя» и не говорит, активен он или нетВ противном случае .NET автоматически инициализирует значение свойства «Active» пакета как «false», и в результате все отключенные пакеты возвращаются с именем или частью имени, выбранным пользователем.

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

Большое спасибо за внимание и ответ. Я смог РЕШИТЬ ПРОБЛЕМУ после некоторых испытаний и идеи, которую Пшемек Марцинкевич дал мне в своем ответе. Да ладно, этот ответ может помочь многим в будущем. Мне нужно было сделать свойства класса 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% гибким для моих нужд.

Я действительно надеюсь, что эти усилия помогут кому-то в сообществе.

0 голосов
/ 11 июля 2019

Сделайте свойство Активным обнуляемым (чтобы оно соответствовало типу поля в базе данных), и это решит вашу проблему.

Класс сущности:

public class Package
{
    ...
    public Boolean? Active { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...