ASP.NET MVC Урок 1-F / ASP.NET MVC Урок C
.pdfБаза данных
Переходим к самому важному разделу, работе с БД. Например, у нас есть объект типа Post (блогозапись), которая, естественно, должна быть на двух языках:
ID |
Уникальный номер записи |
|
|
|
|
UserID |
Автор записи |
|
|
|
|
Header |
Заголовок |
Требует перевода |
|
|
|
Url |
Url записи |
|
|
|
|
Content |
Содержимое записи |
Требует перевода |
|
|
|
AddedDate |
Дата добавления |
|
|
|
|
Итак, как это всё будет организовано:
Создадим таблицу Language, где и будут определены языки
Создадим таблицу Post, где будут все поля, не требующие перевода
Создадим таблицу PostLang, связанную с Post и Language, где будет перевод необходимых полей для таблицы Post и связанный с таблицей Language
Ок, теперь добавим это в LessonProject.Model (LessonProject.Model/IRepository.cs):
UHJLRQ /DQJXDJH
,4XHU\DEOH /DQJXDJH! /DQJXDJHV ^JHW`
ERRO &UHDWH/DQJXDJH/DQJXDJH LQVWDQFH
ERRO 8SGDWH/DQJXDJH/DQJXDJH LQVWDQFH
ERRO 5HPRYH/DQJXDJH LQWLG/DQJXDJH
HQGUHJLRQ
UHJLRQ 3RVW
,4XHU\DEOH 3RVW! 3RVWV ^JHW`
ERRO &UHDWH3RVW3RVW LQVWDQFH
ERRO 8SGDWH3RVW3RVW LQVWDQFH
ERRO 5HPRYH3RVW LQWLG3RVW
HQGUHJLRQ
Создаем модели с помощью уже созданных сниппетов /Proxy/Language.cs:
QDPHVSDFH /HVVRQ3URMHFW 0RGHO
^
SXEOLF SDUWLDO FODVV /DQJXDJH
^
`
`
/Proxy/Post.cs:
QDPHVSDFH /HVVRQ3URMHFW 0RGHO
^
SXEOLF SDUWLDO FODVV 3RVW
^
`
`
/SqlRepository/Language.cs:
SXEOLF SDUWLDO FODVV 6TO5HSRVLWRU\
^
SXEOLF,4XHU\DEOH /DQJXDJH! /DQJXDJHV
^
JHW
^
UHWXUQ'E /DQJXDJHV
`
`
SXEOLF ERRO &UHDWH/DQJXDJH/DQJXDJH LQVWDQFH
^
LILQVWDQFH ,'
^
'E /DQJXDJHV ,QVHUW2Q6XEPLW LQVWDQFH
'E /DQJXDJHV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
SXEOLF ERRO 8SGDWH/DQJXDJH/DQJXDJH LQVWDQFH
^
/DQJXDJH FDFKH 'E /DQJXDJHV :KHUH S ! S ,' LQVWDQFH ,' )LUVW2U'HIDXOW
LIFDFKH QXOO
^
FDFKH &RGH LQVWDQFH &RGH
FDFKH 1DPH LQVWDQFH 1DPH
'E /DQJXDJHV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
SXEOLF ERRO 5HPRYH/DQJXDJH LQWLG/DQJXDJH
^
/DQJXDJH LQVWDQFH 'E /DQJXDJHV :KHUH S ! S ,' LG/DQJXDJH )LUVW2U'HIDXOW
LILQVWDQFH QXOO
^
'E /DQJXDJHV 'HOHWH2Q6XEPLW LQVWDQFH
'E /DQJXDJHV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
`
/SqlRepository/Post.cs:
SXEOLF SDUWLDO FODVV 6TO5HSRVLWRU\
^
SXEOLF,4XHU\DEOH 3RVW! 3RVWV
^
JHW
^
UHWXUQ'E 3RVWV
`
`
SXEOLF ERRO &UHDWH3RVW3RVW LQVWDQFH
^
LILQVWDQFH ,'
^
'E 3RVWV ,QVHUW2Q6XEPLW LQVWDQFH
'E 3RVWV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
SXEOLF ERRO 8SGDWH3RVW3RVW LQVWDQFH
^
3RVW FDFKH 'E 3RVWV :KHUH S ! S ,' LQVWDQFH ,' )LUVW2U'HIDXOW
LIFDFKH QXOO
^
72'2 8SGDWH ILHOGV IRU 3RVW
'E 3RVWV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
SXEOLF ERRO 5HPRYH3RVW LQWLG3RVW
^
3RVW LQVWDQFH 'E 3RVWV :KHUH S ! S ,' LG3RVW )LUVW2U'HIDXOW
LILQVWDQFH QXOO
^
'E 3RVWV 'HOHWH2Q6XEPLW LQVWDQFH
'E 3RVWV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
`
Итак, у нас есть набор PostLangs в объекте класса Post, где и хранятся различные переводы. Причем, перевод на английский или русский язык может быть, так может и не быть. Но, по крайней мере, хотя бы один язык должен быть. Что необходимо сделать для этого:
Добавим языковые поля в Post (Header, Content)
Создадим свойство CurrentLang, при изменении которого будут инициализироваться языковые поля.
При создании записи в БД Post автоматически создается запись в БД PostLang.
При изменении записи в БД, проверяется, какой именно язык изменяется, и если такого языка (перевода) еще нет, то создается новая запись PostLang в БД:
Перейдем к реализации (/Proxy/Post.cs):
SXEOLF SDUWLDO FODVV 3RVW
^
SULYDWH LQWBFXUUHQW/DQJ
SXEOLF LQW&XUUHQW/DQJ
^
JHW
^
UHWXUQBFXUUHQW/DQJ
`
VHW
^
BFXUUHQW/DQJ YDOXH
YDUFXUUHQW/DQJ 3RVW/DQJV )LUVW2U'HIDXOW S ! S /DQJXDJH,' YDOXH
LIFXUUHQW/DQJ QXOO
^
,V&RUUHFW/DQJ IDOVH
YDUDQ\/DQJ 3RVW/DQJV )LUVW2U'HIDXOW
LIDQ\/DQJ QXOO
^
6HW/DQJ DQ\/DQJ
`
`
HOVH
^
,V&RUUHFW/DQJ WUXH
6HW/DQJ FXUUHQW/DQJ
`
`
`
SULYDWH YRLG 6HW/DQJ3RVW/DQJ SRVW/DQJ
^
+HDGHU SRVW/DQJ +HDGHU
&RQWHQW SRVW/DQJ &RQWHQW
`
SXEOLF ERRO,V&RUUHFW/DQJ ^JHW SURWHFWHG VHW`
SXEOLF VWULQJ+HDGHU ^JHW VHW`
SXEOLF VWULQJ&RQWHQW ^JHW VHW`
`
Тут важно заметить, что если необходимого перевода нет, то берется первый попавшийся, и устанавливается IsCorrectLang = false. Это для того, что лучше показать пользователю хоть какуюто информацию, чем не показать ничего.
Создание/изменение объекта Post (/SqlRepository/Post.cs):
SXEOLF ERRO &UHDWH3RVW3RVW LQVWDQFH
^
LILQVWDQFH ,'
^
LQVWDQFH$GGHG'DWH 'DWH7LPH 1RZ
'E 3RVWV ,QVHUW2Q6XEPLW LQVWDQFH
'E 3RVWV &RQWH[W 6XEPLW&KDQJHV
YDUODQJ 'E /DQJXDJHV )LUVW2U'HIDXOW S ! S ,' LQVWDQFH &XUUHQW/DQJ
LIODQJ QXOO
^
&UHDWH2U&KDQJH3RVW/DQJ LQVWDQFHQXOOODQJ
UHWXUQ WUXH
`
`
UHWXUQ IDOVH
`
SXEOLF ERRO 8SGDWH3RVW3RVW LQVWDQFH
^
3RVW FDFKH 'E 3RVWV :KHUH S ! S ,' LQVWDQFH ,' )LUVW2U'HIDXOW
LIFDFKH QXOO
^
FDFKH 8UO LQVWDQFH 8UO
'E 3RVWV &RQWH[W 6XEPLW&KDQJHV
YDUODQJ 'E /DQJXDJHV )LUVW2U'HIDXOW S ! S ,' LQVWDQFH &XUUHQW/DQJ
LIODQJ QXOO
^
&UHDWH2U&KDQJH3RVW/DQJ LQVWDQFH FDFKH ODQJ
UHWXUQ WUXH
`
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
SULYDWH YRLG &UHDWH2U&KDQJH3RVW/DQJ3RVW LQVWDQFH 3RVW FDFKH /DQJXDJH ODQJ
^
3RVW/DQJ SRVW/DQJ QXOO
LIFDFKH QXOO
^
SRVW/DQJ 'E 3RVW/DQJV )LUVW2U'HIDXOW S ! S 3RVW,' FDFKH ,' S /DQJXDJH,' ODQJ ,'
`
LISRVW/DQJ QXOO
^
YDUQHZ3RVW/DQJ QHZ3RVW/DQJ
^
3RVW,' LQVWDQFH ,'
/DQJXDJH,' ODQJ ,'
+HDGHU LQVWDQFH +HDGHU
&RQWHQW LQVWDQFH &RQWHQW
`
'E 3RVW/DQJV ,QVHUW2Q6XEPLW QHZ3RVW/DQJ
`
HOVH
^
SRVW/DQJ +HDGHU LQVWDQFH +HDGHU
SRVW/DQJ &RQWHQW LQVWDQFH &RQWHQW
`
'E 3RVW/DQJV &RQWH[W 6XEPLW&KDQJHV
`
Рассмотрим, как работает CreateOrChangePostLang функция:
При вызове данной функции, мы ищем в Language необходимый язык. Если язык не найден, то вызова не происходит, и мы не создаем PostLang объект (т.е. перевод)
Если мы находим необходимый язык, то вызываем CreateOrChangePostLang:
Если cache нулевое (объект PostLang еще точно не создан) или
Если cache не нулевое, но перевод не найден, то
Создаем перевод (запись в БД PostLang) Иначе изменяем перевод, который найден.
При удалении записи Post все PostLang удаляются по связи OnDelete = cascade (проследите за этим)
В БД должны быть уже добавлены записи для необходимых языков:
1 |
Ru |
Русский |
2 |
En |
Английский |
|
|
|
Админка Сейчас, чтобы это всё продемонстрировать, мы создадим админку. План действий таков (мы его
еще потом доработаем и озвучим):
Создать модели
Связать язык ввода и пользователя (для того, чтобы было понятно, в каком языке работает администратор или редактор)
Создать переключение между языками
Создать домашнюю страницу админки
Создать контроллер по работе с постами Вывести посты в default/postController части
Добавим в таблицу User LanguageID:
Добавляем в IRepository.cs:
ERRO &KDQJH/DQJXDJH8VHU LQVWDQFHVWULQJ/DQJ&RGH
Реализуем в /SqlRepository/User.cs:
SXEOLF ERRO &KDQJH/DQJXDJH8VHU LQVWDQFHVWULQJ/DQJ&RGH
^
YDUFDFKH 'E 8VHUV )LUVW2U'HIDXOW S ! S ,' LQVWDQFH ,'
YDUQHZ/DQJ 'E /DQJXDJHV )LUVW2U'HIDXOW S ! S &RGH /DQJ&RGH
LIFDFKH QXOO QHZ/DQJ QXOO
^
FDFKH /DQJXDJH QHZ/DQJ
'E 8VHUV &RQWH[W 6XEPLW&KDQJHV
UHWXUQ WUXH
`
UHWXUQ IDOVH
`
Создаем модель /Models/ViewModel/PostView.cs:
SXEOLF FODVV 3RVW9LHZ
^
SXEOLF LQW,' ^JHW VHW`
SXEOLF LQW8VHU,' ^JHW VHW`
SXEOLF ERRO,V&RUUHFW/DQJ ^JHW VHW`
SXEOLF LQW&XUUHQW/DQJ ^JHW VHW`
>5HTXLUHG (UURU0HVVDJH ȼɜɟɞɢɬɟ ɡɚɥɨɝɨɜɨɤ@
SXEOLF VWULQJ+HDGHU ^JHW VHW`
>5HTXLUHG@
SXEOLF VWULQJ8UO ^JHW VHW`
>5HTXLUHG (UURU0HVVDJH ȼɜɟɞɢɬɟ ɫɨɞɟɪɠɢɦɨɟ@
SXEOLF VWULQJ&RQWHQW ^JHW VHW`
`
Строки валидации не надо вставлять в GlobalRes, так как тут мы работаем только в админке и это нам ни к чему (так как администраторы люди скромные). Но если есть другие требования, то мы знаем что делать.
Создаем /Areas/Admin/Controller/AdminController.cs:
SXEOLF DEVWUDFW FODVV $GPLQ&RQWUROOHU %DVH&RQWUROOHU
^
SXEOLF/DQJXDJH &XUUHQW/DQJ
^
JHW
^
UHWXUQ&XUUHQW8VHU QXOO" &XUUHQW8VHU /DQJXDJHQXOO
`