Я хотел бы спросить, является ли мое решение Linq ниже хорошим решением или есть лучший способ. Я новичок в использовании Linq и наиболее знаком с MySQL. Итак, я конвертировал один из моих прошлых проектов из PHP в .NET MVC и пытаюсь выучить Linq. Я хотел бы узнать, есть ли лучшее решение, чем то, которое я придумал.
У меня есть следующие структуры таблиц:
CREATE TABLE maplocations (
ID int NOT NULL AUTO_INCREMENT,
name varchar(35) NOT NULL,
Lat double NOT NULL,
Lng double NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY name (name)
);
CREATE TABLE reservations (
ID INT NOT NULL AUTO_INCREMENT,
loc_ID INT NOT NULL,
resDate DATE NOT NULL,
user_ID INT NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY one_per (loc_ID, resDate),
FOREIGN KEY (user_ID) REFERENCES Users (ID),
FOREIGN KEY (loc_ID) REFERENCES MapLocations (ID)
);
CREATE TABLE Users (
ID INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
email VARCHAR(50) NOT NULL,
pass VARCHAR(128) NOT NULL,
salt VARCHAR(5) NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY unique_names (name),
UNIQUE KEY unique_email (email)
);
В MySQL я использую следующий запрос, чтобы получить самое простое резервирование для каждого местоположения карты с ненулевой датой для любых местоположений, у которых нет резервирования.
SELECT locs.*, if(res.resDate,res.resDate,'0001-01-01') as resDate, res.Name as User
FROM MapLocations locs
LEFT JOIN (
SELECT loc_ID, resDate, Name
FROM Reservations, Users
WHERE resDate >= Date(Now())
AND user_ID = Users.ID
ORDER BY resDate
) res on locs.ID = res.loc_ID
group by locs.ID
ORDER BY locs.Name;
В Linq, когда Visual Studio автоматически создает большую часть структуры после подключения к базе данных, я придумал следующий эквивалент этого SQL-запроса
var resList = (from res in Reservations
where res.ResDate >= DateTime.Today
select res);
var locAndRes =
(from loc in Maplocations
join res in resList on loc.ID equals res.Loc_ID into join1
from res2 in join1.DefaultIfEmpty()
join usr in Users on res2.User_ID equals usr.ID into join2
from usr2 in join2.DefaultIfEmpty()
orderby loc.ID,res2.ResDate
select new {
ID = (int)loc.ID,
Name = (string)loc.Name,
Lat = (double)loc.Lat,
Lng = (double)loc.Lng,
resDate = res2 != null ?(DateTime)res2.ResDate : DateTime.MinValue,
user = usr2 != null ? usr2.Name : null
}).GroupBy(a => a.ID).Select(b => b.FirstOrDefault());
Итак, мне интересно, есть ли лучший способ выполнить этот запрос?
Это эквивалентно?
Есть ли хорошие практики, которым я должен следовать?
Кроме того, еще один вопрос, у меня проблемы с получением этого из var
в Список. делать что-то подобное не работает
List<locAndResModel> locList = locAndRes.AsQueryable().ToList<locAndResModel>();
В приведенном выше фрагменте locAndResModel
- это просто класс, в котором есть переменные для соответствия int, string, double double, DateTime, строковых результатов запроса. Есть ли простой способ получить список без необходимости использовать foreach и передавать результаты в переопределение конструктора? Или мне просто добавить его в ViewData и вернуть View?