2012-02-10 3 views
0

下記の私の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に追加してビューを返すだけですか?

+0

Entity Frameworkを使用していますか?もしそうなら外来キーを持っているなら、あなたのためにすでに参加しているものもあります。また、ToListで宣言された型に匿名型を強制することはできません。選択したタイプの新しいインスタンスを使用する必要があります。 – JamieSee

+0

@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

答えて

0

Entity Frameworkによって実行される自動結合を利用したいと思うでしょう。これを試してみて、あなたが望むことができたら教えてください:

var locAndRes = from maplocation in MapLocations 
       let earliestReservationDate = maplocation.Reservations.Min(res => res.resDate) 
       let earliestReservation = (from reservation in mapLocation.Reservations 
              where reservation.resDate == earliestReservationDate && reservation.resDate >= DateTime.Today 
              select reservation).FirstOrDefault() 
       select new locAndResModel(maplocation.ID, maplocation.name, maplocation.Lat, maplocation.Lng, earliestReservation != null ? earliestReservation.resDate : DateTime.MinValue, earliestReservation != null ?earliestReservation.User.name : null) 
+0

MySQL.Data.Entity.SqlGenerator.Visitから来る「指定されたメソッドがサポートされていない」ということを除いて、すべてがうまくいくように見える – Gamil

+0

@Gamil申し訳ありませんtypoedし、FirstOrDefaultからparensを残しました。それが修正されているかどうか確認してください。 – JamieSee

+0

私はそれをVSに入れたときに気づいた。そしてまた、あなたの助けに感謝します。私は少し掘り下げましたが、それはMySQLとEntity Frameworkのものと思われます。私はこの問題についていくつかの記事を見てきましたが、しばしばMySQLではなくMSSQLで正常に動作します。だから私はMSSQL(学術目的のために)でそれを試してみて、それがどのように行くかを教えてください。 – Gamil

関連する問題