1

私は雇用主のために管理しなければならない古い ASP/ASP.Net Web アプリのいくつかを更新する目的で MVC を学んでいます。

私が学ぶのを助けるための私の例では、私は自動車販売店を持っています。各 DealerShip には、レンタルする車が多数あります。Car は CarType として分類され、各 CarType には多数の Car を関連付けることができます。

CarType.cs

//
// Holds types of car - this has a one to many relationship with Car class
//
[Table("tType")]
public class CarType
{
    [Key]
    public int type_id { get; set; }
    public int dealer_id { get; set; }
    public string type_name { get; set; }
    public string type_desc { get; set; }
    public virtual ICollection<Car> Car { get; set; }
}  


Car.cs

//
// Holds actual Cars
//

[Table("tCar")]
public class Car
{
    [Key]
    public int car_id { get; set; }
    public int dealer_id { get; set; }
    public int type_id { get; set; }
    public int car_order { get; set; }
    public string car_name { get; set; }
    public virtual ICollection<Rental> Rentals { get; set; }
    public virtual CarType CarType { get; set; }
}


Rental.cs

//
// This holds records of when cars are hired, and for which dealer, and for how long
//

[Table("tRental")]
public class Rental
{
    [Key]
    public int rental_id { get; set; }
    public int dealer_id { get; set; }
    public int car_id { get; set; }
    public DateTime hire_from { get; set; }
    public DateTime hire_to { get; set; }
    public virtual Car Car { get; set; }


}

上記のクラスは私のデータベースにマップされます。このようなモデルの使用は避けるべきであり、代わりにViewModelを使用する必要があることを読みました。

この例でやりたいことは、指定された日付と必要な雇用日数で特定のディーラーを検索できるようにすることです。

次に、ビューモデルに次のものを入力します。

  1. 車が必要な日付から
  2. 車が必要な日数
  3. DealerID (URL から取得されます - 例: http://mycars.com/search/avail/dealerGlasgow )
  4. 取り扱い車種一覧
  5. 車種ごとの台数

これを行うために、以下の ViewModel を思い付きました。

SearchViewModel.cs

public class SearchViewModel
{
    [Required]
    public DateTime From { get; set; }
    [Required]
    public int DaysHire { get; set; }
    public int dealer_id { get; set; }
    public IQueryable<Car> Cars { get; set; }
}

ここで、このビュー モデルを使用して、ASP.Net MVC でカレンダーと日数の検索フォームを表示します。そのため、フォームの非表示フィールド (URL から取得) から deal_id を入力し、以下の LINQ を使用してデータベースを検索します。私のコントローラーで。

検索は、最初に、その人が雇おうとしている日付と重複するレンタルを探します。その情報は次の場所に配置されます。

preBookedCars

次に、dealer_id で Cars を検索し、すでに雇用されているものを除外します。

freeCars

コントローラーのコードは次のとおりです。

    //
    // POST: /Search/Avail/DealerName

    [AllowAnonymous]
    [HttpPost]
    public ActionResult Avail(SearchViewModel model, string id)
    {
        if (ModelState.IsValid)
        {
            var dteFrom = model.From;
            var dteTo = model.From.AddDays(model.Days);

            // Search for any bookings for those dates, for the dealer specifed

            var prebookedCars = db.Cars
                .Where(car => car.Rentals.Any(rental =>
                    (model.dealer_id == rental.dealer_id && dteFrom >= rental.check_in && dteFrom < rental.check_out)
                    ||
                    (model.dealer_id == rental.dealer_id && dteTo > rental.check_in && dteTo <= rental.check_out)
                    ||
                    (model.dealer_id == rental.dealer_id && dteFrom <= rental.check_in && dteTo >= rental.check_out)
                ));

            // Search for Cars, include the Car Type (so we can have description etc), and exclude any cars that have already been hired

            var freeCars = db.Cars.Include("CarType")
                .Where(car => car.dealer_id == model.dealer_id)
                .Except(prebookedCars)
                .OrderBy(o => o.car_order);


            model.Cars = freeCars;

            return View(model);
        }
        else
        {
            return View(model);
        }


    }

いくつか質問があります:

a) prebookedCars の Linq は効率的ですか? 以下を確認する方法はありますか?

model.dealer_id == rental.dealer_id

...3 回ではなく 1 回だけ (たとえば、2 つの Where 句を使用)?

b) VS でモデルをステップ実行するときのクエリ - モデル内の各車について、VS でクリックダウンできます。model.Cars.[Results View].Rentals - その車に関連付けられたすべてのレンタルを表示します - すでに予約されている車を除外したかったのですが。ビューでそのレベルの詳細を使用しない場合、このリストがモデル内にあることは重要ですか? または、そこにあるという事実は、モデル/クエリに不要なオーバーヘッドを追加していることを意味しますか?

c)私は本当に、私のビューで、表示できるようになりたいと思っていました:

CarType (type_name) と Description (type_desc) - ドロップダウン ボックスには、そのタイプの利用可能な車の数が表示されます。

私が最終的に得たのは、表示できるのではなく、特定の個々の車です。

model.CarType.type_name および model.CarType.count

クエリを変更して、利用可能な車種の数を返すにはどうすればよいですか (または、上記のモデルで何とかできますか?)

私はこれが非常に長く続いていることを知っています-しかし、詳細を示すことが役立つと思いました-誰かが私のクエリの一部を助けることができれば、私はそれを感謝します.

ありがとう、マーク

4

1 に答える 1

2

a) prebookedCars の Linq は効率的ですか? 以下を確認する方法はありますか?

model.dealer_id == Rental.dealer_id ...3 回ではなく 1 回だけ (たとえば、Where 句を 2 つ持つなど)?

最初に model.dealer_id のテストを配置するようにステートメントを変更できます。

db.Cars.Where(car => car.Rentals.Any(rental =>
                    (model.dealer_id == rental.dealer_id) && (
                    (dteFrom >= rental.check_in && dteFrom < rental.check_out)
                    ||
                    (dteTo > rental.check_in && dteTo <= rental.check_out)
                    ||
                    (dteFrom <= rental.check_in && dteTo >= rental.check_out))
                ));

B について: いくつか間違っている可能性があります。このために最初にコードを使用していますか?その場合は、Equals 関数を実装する必要があるか、linq のキャストが必要になる可能性があります。 この記事は関連している可能性があります

C について: ご質問の意味がよくわかりませんが、特定の車種の利用可能な車を数えて表示したいとお考えですか? その場合、車の種類のリストを繰り返し処理しているときに、利用可能な車の列挙が既にあるため (b が機能すると仮定)、前のクエリから利用可能な車の数を取得できます。

 foreach (var cartype in db.CarTypes)
            {
                var numberAvailable = freeCars.Where(fc => fc.CarType == cartype);
            }

これは一種の疑似コードであり、ループが表示されるはずであり、おそらく他の多くのことを行っているでしょうが、アイデアが得られることを願っています.

于 2012-08-03T15:24:56.643 に答える