Как сделать запрос хранения таблицы Azure по пустым полям? - PullRequest
0 голосов
/ 09 мая 2018

У меня есть таблица с пустыми полями:

public int? Order {get; set;}
public DateTime? StartDate {get; set;}
public DateTime? EndDate {get; set;}
public string Text {get; set;}

Все эти поля могут иметь значение NULL

Проблема начинается, когда я хочу запросить записи

  • , где Order, StartDate, EndDate и Text не равны NULL или

  • , где Order, StartDate и Text не равны NULL, но EndDate имеет значение NULL или

  • , где Порядок и Текст не равны нулю, а StartDate и EndDate равны нулю

    Order.HasValue && StartDate.HasValue && EndDate.HasValue && !string.IsNullOrEmpty(Text) || Order.HasValue && StartDate.HasValue && !EndDate.HasValue && !string.IsNullOrEmpty(Text) || Order.HasValue && !StartDate.HasValue && !EndDate.HasValue && !string.IsNullOrEmpty(Text)

Используя такой запрос, я получаю ошибку или 400 (неверный запрос) или неподдерживаемый оператор (isnullorempty не поддерживается)

Согласно этому ответу https://stackoverflow.com/a/4263091/3917754 невозможно запросить значения NULL ...

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Нельзя запросить нулевое значение в хранилище таблиц Azure, string не является исключением из этого. Свойство с нулевым значением не существует в табличной форме при записи в таблицу Azure, поэтому запросы, ссылающиеся на это свойство, всегда будут возвращать неожиданный результат. В качестве обходного пути вы можете предоставить ненулевые значения по умолчанию и запросить их. В случае string присвоение значения "" string позволяет запросить строку. Пусто (не null, поскольку "" не равно null). Для типа DateTime? опять тот же обходной путь, но вместо "" можно назначить скрытое значение по умолчанию, т.е. DateTime.MinValue (или MaxValue), если фактическое значение свойства равно нулю, иначе вы можете преобразовать его в string и назначить пустую строку в качестве значения по умолчанию, но вам нужно заплатить цену за преобразование туда и обратно, поэтому я лично я предпочитаю избегать этого, если это возможно.

0 голосов
/ 09 мая 2018

AFAIK, вы не можете установить DateTime на ноль или пусто. Итак, я предлагаю вам сохранить дату и время в виде строки, а когда вы хотите отобразить модель для просмотра, вы можете преобразовать строку в DateTime.

Когда вы вставляете объект, конвертируйте DateTime в строку:

    TableBatchOperation batchOperation = new TableBatchOperation();
    DateTime dts = DateTime.Now;
    DateTime dte = DateTime.UtcNow;

    // Create a customer entity and add it to the table.
    CustomerEntity customer1 = new CustomerEntity("Smith", "Jeff");
    customer1.Order = 1;
    customer1.StartDate = Convert.ToString(dts);
    customer1.EndDate = Convert.ToString(dte);
    customer1.Text = "text1";

    // Create another customer entity and add it to the table.
    CustomerEntity customer2 = new CustomerEntity("Smith", "Ben");
    customer2.Order = 2;
    customer2.StartDate = Convert.ToString(dts);
    customer2.EndDate = "";
    customer2.Text = "text2";

    CustomerEntity customer3 = new CustomerEntity("Smith", "Cai");
    customer3.Order = 3;
    customer3.StartDate = "";
    customer3.EndDate = "";
    customer3.Text = "text3";

    // Add both customer entities to the batch insert operation.
    batchOperation.Insert(customer1);
    batchOperation.Insert(customer2);
    batchOperation.Insert(customer3);

    // Execute the batch operation.
    table.ExecuteBatch(batchOperation);

Сущность, как показано ниже:

public class CustomerEntity : TableEntity
        {
            public CustomerEntity(string lastName, string firstName)
            {
                this.PartitionKey = lastName;
                this.RowKey = firstName;
            }

            public CustomerEntity() { }

            public int? Order { get; set; }
            public string StartDate { get; set; }
            public string EndDate { get; set; }
            public string Text { get; set; }

            public DateTime? ConvertTime(string dateStr)
            {
                if (string.IsNullOrEmpty(dateStr))
                    return null;
                DateTime dt;
                var convert=DateTime.TryParse(dateStr, out dt);
                return dt;
            }
        }

Когда вы показываете его или сопоставляете с моделью, вы можете использовать метод ConvertTime, чтобы определить, является ли столбец нулевым с ConvertTime(entity.StartDate). Если это значение равно NULL, оно будет иметь значение NULL, а если оно имеет значение, оно преобразует строку в DateTime.

            string orderhasvalue = TableQuery.GenerateFilterCondition("Order", QueryComparisons.NotEqual, null);
            string startdatehasvalue = TableQuery.GenerateFilterCondition("StartDate", QueryComparisons.NotEqual, null);
            string enddatehasvalue = TableQuery.GenerateFilterCondition("EndDate", QueryComparisons.NotEqual, null);
            string texthasvalue = TableQuery.GenerateFilterCondition("Text", QueryComparisons.NotEqual, null);
            string startdatenothasvalue = TableQuery.GenerateFilterCondition("StartDate", QueryComparisons.Equal, null);
            string enddatenothasvalue = TableQuery.GenerateFilterCondition("EndDate", QueryComparisons.Equal, null);

            TableQuery<CustomerEntity> query1 = new TableQuery<CustomerEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.CombineFilters(
                        TableQuery.CombineFilters(
                            orderhasvalue, TableOperators.And, startdatehasvalue),
                    TableOperators.And, enddatehasvalue),
                TableOperators.And, texthasvalue)
            );
            TableQuery<CustomerEntity> query2 = new TableQuery<CustomerEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.CombineFilters(
                        TableQuery.CombineFilters(
                            orderhasvalue, TableOperators.And, startdatehasvalue),
                    TableOperators.And, enddatenothasvalue),
                TableOperators.And, texthasvalue)
            );
            TableQuery<CustomerEntity> query3 = new TableQuery<CustomerEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.CombineFilters(
                        TableQuery.CombineFilters(
                            orderhasvalue, TableOperators.And, startdatenothasvalue),
                    TableOperators.And, enddatenothasvalue),
                TableOperators.And, texthasvalue)
            );

            // Print the fields for each customer.
            foreach (CustomerEntity entity in table.ExecuteQuery(query2))
            {

                Console.WriteLine("{0}, {1}\t{2}\t{3}\t{4}\t{5}", entity.PartitionKey, entity.RowKey,
                    entity.Order, entity.ConvertTime(entity.StartDate), entity.ConvertTime(entity.EndDate), entity.Text);
            }
...