下記の私のLinqソリューションが良い解決策であるか、より良い方法があるかどうかお尋ねします。私はLinqを初めて使用しています.MySQLをよく知っています。だから私は過去のプロジェクトの1つをPHPから.NET MVCに変換しており、Linqを学びたいと思っています。私は、私が思いついたより良い解決策があるかどうかを知りたいと思います。ユニークなデータを持つ左ジョイント用のエレガントなlinqソリューション
I持って、次のテーブル構造:
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では、私がいない任意の場所のための非ヌル日付で各maplocationでealiest予約を取得するために、次のクエリを使用します予約があります。
のLINQで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;
は、Visual Studioが自動的にデータベースに接続した後、構造の多くを作成すると、私は、
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());
だから、SQLクエリに次の同等が出ています私はこのクエリを実行する良い方法があるのだろうか? これは同等ですか? 私に従うべき良い習慣はありますか?
また、もう1つ質問しますと、これをvar
からリストに取得することができません。このような何かを行うと、上記のスニペットlocAndResModel
で
List<locAndResModel> locList = locAndRes.AsQueryable().ToList<locAndResModel>();
動作しないだけでint型と一致するように、変数を持つクラスは、文字列、ダブルダブル、日時、クエリ文字列の結果です。 foreachを実行せずに結果をコンストラクタオーバーライドに渡すことなくリストを取得する簡単な方法はありますか?または、ViewDataに追加してビューを返すだけですか?
Entity Frameworkを使用していますか?もしそうなら外来キーを持っているなら、あなたのためにすでに参加しているものもあります。また、ToListで宣言された型に匿名型を強制することはできません。選択したタイプの新しいインスタンスを使用する必要があります。 – JamieSee
@James応答いただきありがとうございます。はい、Entityフレームワークを使用しています。私はむしろそれにも新しいです。私はselect内でlocAndResModelを使用することはありません。これは最後のクエリでうまくいくようです: 'select new locAndResModel((int)loc.ID、(string)loc.name、(double)loc.Lat、(double)loc.Lng、res2!= null?( DateTime)res2.resDate:DateTime.MinValue、(文字列)usr2.name) ' – Gamil