Соединение дополнительной информации с перечислением.NET

Я бы сказал, что если у вас нет веских причин, хранить значения, которые можно легко вычислить на уровне запроса, является ошибкой.

Это похоже на один из многих случаев, которые я видел, когда люди думают, что они что-то получают, сохраняя значения в одной таблице, которая рассчитывается из значений другой таблицы, но на самом деле все наоборот - теперь у вас есть две точки данных, которые должны быть синхронизированы всегда, и поскольку процесс, синхронизирующий их, является триггером, вы на самом деле не можете это контролировать - например, довольно легко отключить / включить триггеры.

Поэтому, Мой совет вам будет удалить этот триггер все вместе и просто вычислить значение, когда вам нужно.

Обратите внимание, что поскольку SQL Server поддерживает max() over(partition by) , то есть вам даже не нужно group by, если вы хотите вычислить максимум столбца.

Обновлено После ваших комментариев к ответу, похоже, у вас есть веская причина сохранить эти значения.

Сказав все это, вот прямой ответ на вопрос, который вы задали.
В триггерах SQL Server база данных позволяет запрашивать две специальные таблицы, называемые inserted и deleted . Эти таблицы содержат данные, которые были (или будут в случае instead of триггеров) вставлены или удалены в таблицу, в которой объявлен триггер.

Обратите внимание, что в SQL Server триггеры запускаются для каждого оператора, а не для строки. Это означает, что таблицы inserted и deleted могут содержать 0, 1 или много строк.

Если вы все еще хотите рассчитать значение с использованием триггеров, я бы посоветовал триггер для вставки / обновления и другой триггер для удалений.

Это сделало бы намного более простой код.

В триггере удаления вы оставили присоединение к таблице deleted:

UPDATE T
SET QARTOD = MaxValue
FROM factMeasures As T
JOIN 
(
    SELECT d.fkMeasureID, Max(t.RuleValue) As MaxValue
    FROM Deleted AS d
    LEFT JOIN dt_QCflags As t
        ON d.QC_ID = t.QC_ID
    GROUP BY d.fkMeasureID
) as D
    ON T.MeasureID = D.fkMeasureID

В триггере вставки / обновления вы пишете очень похожий код - но вам не нужно ссылаться на физическая таблица в этом случае, только таблица inserted:

UPDATE T
SET QARTOD = MaxValue
FROM factMeasures As T
JOIN 
(
    SELECT fkMeasureID, Max(RuleValue) As MaxValue
    FROM Inserted 
    GROUP BY fkMeasureID
) as I
    ON t.MeasureID = I.fkMeasureID

22
задан colithium 25 March 2009 в 06:58
поделиться

5 ответов

Существует ФАНТАСТИЧЕСКИЙ новый способ сделать это в C# 3.0. Ключ является этим красивым фактом: Перечисления могут иметь дополнительные методы! Так, вот то, что можно сделать:

public enum ArrowDirection
{
    North,
    South,
    East,
    West
}

public static class ArrowDirectionExtensions
{
     public static UnitVector UnitVector(this ArrowDirection self)
     {
         // Replace this with a dictionary or whatever you want ... you get the idea
         switch(self)
         {
             case ArrowDirection.North:
                 return new UnitVector(0, 1);
             case ArrowDirection.South:
                 return new UnitVector(0, -1);
             case ArrowDirection.East:
                 return new UnitVector(1, 0);
             case ArrowDirection.West:
                 return new UnitVector(-1, 0);
             default:
                 return null;
         }
     }
}

Теперь, можно сделать это:

var unitVector = ArrowDirection.North.UnitVector();

Сладкий! Я только узнал это приблизительно месяц назад, но это - очень хорошее последствие новых функций C# 3.0.

Вот другой пример на моем блоге.

38
ответ дан 29 November 2019 в 04:40
поделиться

Я вел блог об этом здесь.

Испытайте что-то вроде этого с Атрибутами.

  public enum Status {

    [Status(Description = "Not Available")]      

    Not_Available = 1,      

    [Status(Description = "Available For Game")] 

    Available_For_Game = 2,      

    [Status(Description = "Available For Discussion")] 

    Available_For_Discussion = 3,

  }

  public class StatusEnumInfo {

    private static StatusAttribute[] edesc; 

    public static String GetDescription(object e)

    {

      System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); 

      StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; 

      if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1)         

        return StatusEnumInfo.edesc[0].Description; 

      else         

        return String.Empty;

    } 

    public static object GetEnumFromDesc(Type t, string desc)

    {

      Array x = Enum.GetValues(t); 

      foreach (object o in x) {

        if (GetDescription(o).Equals(desc)) {

          return o;

        }

      } return String.Empty;

    }

  }

  public class StatusAttribute : Attribute {

    public String Description { get; set; }

  }



  public class Implemenation {

    public void Run()

    {

      Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); 

      String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion);

    }

  }

Вместо Описания используйте свое пользовательское Свойство

3
ответ дан 29 November 2019 в 04:40
поделиться
using System.ComponentModel;
using System.Reflection;


public enum ArrowDirection
{

[Description("Northwards")]
North,

[Description("Southwards")]
South,

[Description("Eastwards")]
East,

[Description("Westwards")]
West
}

...

Создайте дополнительный метод для получения списка описаний:

public static class Enum<T> where T : struct
{

    /// <summary>
    /// Gets a collection of the enum value descriptions.
    /// </summary>
    /// <returns></returns>
    public static IList<string> GetDescriptions()
    {
        List<string> descriptions = new List<string>();
        foreach (object enumValue in Enum<T>.GetValues())
        {
            descriptions.Add(((Enum)enumValue).ToDescription());
        }
        return descriptions;

    }
}
1
ответ дан 29 November 2019 в 04:40
поделиться

Одной вещью, на которую Вы могли посмотреть, является "Безопасный с точки зрения типов Перечислимый" шаблон. Это позволяет Вам создавать перечисление, которое является на самом деле законченным статическим объектом, который может иметь методы/свойства/и т.д..

http://www.javacamp.org/designPattern/enum.html

Joshua Bloch говорит об этом шаблоне в его книге "Эффективный Java". Я использовал его в большом количестве различных ситуаций, и я на самом деле предпочитаю его по простым перечислениям. (Это - агностик языка - это работает в Java, C# или в значительной степени любом языке OO).

0
ответ дан 29 November 2019 в 04:40
поделиться

Ваш подход статического метода кажется довольно чистым мне. Вы инкапсулируете и перечисление и статический метод в том же классе. Изменения в перечислении централизованы в том едином классе.

Добавление метода к перечислению (согласно Java), кажется, добавляет сложность к чему-то, что является действительно очень простым понятием.

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

0
ответ дан 29 November 2019 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: