Можно ли это сделать с помощью Entity Framework 4?Если нет, что может сделать это? - PullRequest
2 голосов
/ 28 августа 2010

Я делаю упрощенную игру тривиального преследования . Я не уверен, смогу ли (и затем как) сделать следующее с EF4: -

У меня есть структура таблицы следующим образом.

Таблица: TrivialPursuitQuestion

=> ID
=> Unique Question
=> AnswerId
=> AnswerType (ie. Geography, Entertainment, etc).

Таблица: ГеографияОтвет

=> ID
=> Place Name
=> LatLong

Таблица: РазвлеченияОтвет:

=> ID
=> Name
=> BordOn
=> DiedOn
=> Nationality .. and other meta data

... и т. Д.

Таким образом, когда человек задает уникальный вопрос ... сохраненный процесс может выяснить, какой это тип ответа (т. Е. Поле AnswerType) ... и, следовательно, выполнить запрос к правильной таблице.

EG.

SELECT @AnswerId = AnswerId, @AnswerType = AnswerType
FROM TrivialPursuitQuestions
WHERE UniqueQuestion = @Question

IF @AnswerId > 0 AND @AnswerType > 0 BEGIN
    IF @AnswerType = 1
        SELECT * 
        FROM GeographicAnswers 
        WHERE AnswerId = @AnswerID

    IF @AnswerType = 2
        SELECT * 
        FROM EntertainmentAnswer
        WHERE AnswerId = @AnswerId

    ... etc ...
END

Теперь .. я не уверен, как это сделать с EF. Прежде всего, сохраненный процесс теперь может возвращать НЕСКОЛЬКО типов результатов .. поэтому я не уверен, действительно ли это плохо.

Тогда я подумал, что, возможно, хранимая процедура должна возвращать множественные наборы записей ... со всеми, кроме одного набора записей, содержащего результат (ы) ... потому что по конструкции будет найден только один тип ответа ...

EG.

-- Same SELECT as above...


IF @AnswerId > 0 BEGIN
    SELECT * 
    FROM GeographicAnswers 
    WHERE AnswerId = CASE @AnswerId WHEN 1 THEN @AnswerID ELSE 0 END

    SELECT * 
    FROM EntertainmentAnswer 
    WHERE AnswerId = CASE @AnswerId WHEN 2 THEN @AnswerID ELSE 0 END

    ... etc ...
END

и это вернет 6 (несколько) наборов записей ... но только один из них должен когда-либо иметь некоторые данные.

Теперь, если это лучшее решение ... возможно ли это с EF4 и как?

Я стараюсь избегать ДВУХ поездок туда и обратно, а также мне нужно выяснить ЧТО пытаться получить ... Я не хочу выяснять это ... Я надеюсь, что с некоторыми умными моделирование системы достаточно умно, чтобы сказать: «О! и это правильный ответ ». Вроде как фабрика ответов (аля Factory Pattern), но с Sql Server + EF4.

У кого-нибудь есть идеи?

1 Ответ

2 голосов
/ 28 августа 2010

В EF Designer вы можете создать объект с именем Answer, а затем создать объекты, полученные из ответа с именем GeographyAnswer, EntertainmentAnswer, ..., используя дискриминатор AnswerType в объекте ответа . Добавьте объект Question. Добавьте ассоциацию из вопроса к Answer, отметьте ее 1: 1. Пусть EF сгенерирует DDL для вашей базы данных.

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

Хотя, это также вызывает вопрос: если это соотношение 1: 1 между вопросом и ответом, почему бы не иметь единую сущность QuestionAnswer и извлечь ее из нее для создания QuestionAnswerGeography, QuestionAnswerEntertainment, ... Сейчас Вы можете легко выбрать Questions определенного типа: например, dataContext.QuestionAnswers.ofType<QuestionAnswerGeography>().

Вот диаграмма сущностей для случая, когда ответом может быть несколько вопросов: alt text

Эта модель позволит вам сделать запрос, подобный этому:

  var geographyQuestions = objectContext.Answers.OfType<Geography>().SelectMany(answer => answer.Questions);

DDL, генерируемый этой моделью: -

-- Creating table 'Answers'
CREATE TABLE [dbo].[Answers] (
    [Id] int IDENTITY(1,1) NOT NULL
);
GO

-- Creating table 'Questions'
CREATE TABLE [dbo].[Questions] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [AnswerId] int  NOT NULL,
    [QuestionText] nvarchar(max)  NOT NULL
);
GO

-- Creating table 'Answers_Geography'
CREATE TABLE [dbo].[Answers_Geography] (
    [PlaceName] nvarchar(max)  NOT NULL,
    [LatLong] nvarchar(max)  NOT NULL,
    [Id] int  NOT NULL
);
GO

-- Creating table 'Answers_Entertainment'
CREATE TABLE [dbo].[Answers_Entertainment] (
    [Name] nvarchar(max)  NOT NULL,
    [BornOn] datetime  NULL,
    [DiedOn] datetime  NULL,
    [Id] int  NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [Id] in table 'Answers'
ALTER TABLE [dbo].[Answers]
ADD CONSTRAINT [PK_Answers]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Questions'
ALTER TABLE [dbo].[Questions]
ADD CONSTRAINT [PK_Questions]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Answers_Geography'
ALTER TABLE [dbo].[Answers_Geography]
ADD CONSTRAINT [PK_Answers_Geography]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Answers_Entertainment'
ALTER TABLE [dbo].[Answers_Entertainment]
ADD CONSTRAINT [PK_Answers_Entertainment]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [AnswerId] in table 'Questions'
ALTER TABLE [dbo].[Questions]
ADD CONSTRAINT [FK_QuestionAnswer]
    FOREIGN KEY ([AnswerId])
    REFERENCES [dbo].[Answers]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_QuestionAnswer'
CREATE INDEX [IX_FK_QuestionAnswer]
ON [dbo].[Questions]
    ([AnswerId]);
GO

-- Creating foreign key on [Id] in table 'Answers_Geography'
ALTER TABLE [dbo].[Answers_Geography]
ADD CONSTRAINT [FK_Geography_inherits_Answer]
    FOREIGN KEY ([Id])
    REFERENCES [dbo].[Answers]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;
GO

-- Creating foreign key on [Id] in table 'Answers_Entertainment'
ALTER TABLE [dbo].[Answers_Entertainment]
ADD CONSTRAINT [FK_Entertainment_inherits_Answer]
    FOREIGN KEY ([Id])
    REFERENCES [dbo].[Answers]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
...