Бизнес-логика, зависящая от строковых значений

В одном из моих проектов, над которым я работаю, я использую Entity Framework 4.1 (Code First). У меня есть отношения между двумя объектами, например:

public class Project
{
    public int Id { get; set; }

    // snip...

    // Foreign Key
    public string ProjectId { get; set; }

    // navigation proeprty
    public virtual ProjectType ProjectType { get; set; }
}

public class ProjectType
{
    public string Id { get; set; }

    public virtual ICollection<Project> Projects { get; set; }
}

Прямо сейчас я использую бизнес-логику, которая зависит от того, какой тип проекта создается/редактируется, поэтому у меня есть такой код:

if( "P".Equals(project.ProjectTypeId) )
    // logic goes here

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


person Dismissile    schedule 11.01.2012    source источник
comment
Является ли полиморфизм вариантом здесь?   -  person Austin Salonen    schedule 12.01.2012
comment
Полезно знать... Думаю, я рад, что не использую EF.   -  person Austin Salonen    schedule 12.01.2012


Ответы (3)


Лично я бы предпочел преобразовать ProjectTypeId в тип перечисления.

var projectType = Enum.Parse(typeof(ProjectType), project.ProjectTypeId);
switch(projectType)
{
    case ProjectType.P: // logic goes here
    case ProjectType.N:
        break;
    default: throw new ArgumentOutOfRangeException("That wasn't a valid project type");
}

Я предполагаю, что у вас есть фиксированное количество ProjectTypes и что ваш код должен знать обо всех них. Этот подход дает вам единый «источник правды», на который можно смотреть, когда вам нужно увидеть все типы ProjectType, которые можно использовать. Я предпочитаю это другим вариантам, таким как класс со строковыми константами, потому что:

  1. Легче «быстро потерпеть неудачу», если вы обнаружите, что проект имеет недопустимый тип проекта.
  2. Вы можете передавать ProjectType в качестве строго типизированных параметров служебным функциям и тому подобному.
person StriplingWarrior    schedule 11.01.2012
comment
@Dismissile: Извините, мне потребовалось некоторое время, чтобы ответить. EF не поддерживает преобразование строк в перечисления, поскольку он материализует данные, но у вас есть ряд обходных путей, таких как свойство, которое выполняет преобразование при первом вызове get. - person StriplingWarrior; 12.01.2012

Я знаю, что на этот вопрос уже был дан ответ, но мы используем несколько иной подход, чем перечисления:

public static class ProjectType
{
    public const string P = "P";
    public const string N = "N";
}

У вас все еще есть единственный источник правды. Как и перечисления, константы определяются во время компиляции. Таким образом, ваш клиентский код будет выглядеть так:

if( ProjectType.P.Equals(project.ProjectTypeId) )
    // logic goes here

По сути, он делает то же самое, но без необходимости в Enum.Parse.

person danludwig    schedule 12.01.2012

Я согласен с Остином, что у вас действительно должно быть что-то вроде ..

открытый класс Project
{
public int Id { get; набор; }

// snip...      

// Foreign Key      
public string ProjectId { get; set; }      

// navigation proeprty      
public virtual IProjectType ProjectType { get; set; }      

}

открытый класс ProjectTypeA: IProjectType
{общедоступный идентификатор строки {получить; набор; }

public virtual ICollection<Project> Projects { get; set; } 

}

открытый класс ProjectTypeB: IProjectType
{общедоступный идентификатор строки {получить; набор; }

public virtual ICollection<Project> Projects { get; set; } 

}

Тогда у вас может быть что-то вроде

если (p.ProjectType - это ProjectTypeB ) {}

или по ссылке

var проекты = из p в Project.ofType выберите p;

person Dimestore Cowboy    schedule 13.01.2012