0

私はこのコード スニペットで正しい行にいると確信していますが、私がやろうとしているのは、次のレコードと前のレコードに移動できるナビゲーション コントロールを使用してページに特定のレコードを表示することです (変更されたバージョンMVC3 で生成された [詳細] ビュー ページの)。

ページに移動すると、コードは ViewBag 変数を介して ActionLink ボタンを初期化し、対応するコントローラー内のこのメソッドで設定されます。

私の質問は、データベース レコードの範囲外に出る問題を防ぎながら、以下を実行するためのより良い方法はありますか?

public ViewResult Details(int id)
{
    //Conditional Statements to manage navigation controls
    if (db.tblQuoteLog.OrderByDescending(x => x.LogDate).Any(x => x.nID < id))
    {
        //Set value next button
        ViewBag.NextID = id;

        ViewBag.PreviousID = db.tblQuoteLog.OrderByDescending(x => x.LogDate).FirstOrDefault(x => x.nID > id).nID; //Inverted logic due to orderby
    }
    else if (db.tblQuoteLog.OrderByDescending(x => x.LogDate).Any(x => x.nID > id))
    {
        ViewBag.NextID = db.tblQuoteLog.OrderByDescending(x => x.LogDate).FirstOrDefault(x => x.nID < id).nID; //Inverted logic due to orderby

        //Set value previous button
        ViewBag.PreviousID = id;
    }
    else
    {
        //Set value next button
        ViewBag.NextID = db.tblQuoteLog.OrderByDescending(x => x.LogDate).FirstOrDefault(x => x.nID < id).nID;

        //Set value previous button
        ViewBag.PreviousID = db.tblQuoteLog.OrderByDescending(x => x.LogDate).FirstOrDefault(x => x.nID > id).nID;
    }

    tblQuoteLog tblquotelog = db.tblQuoteLog.Find(id);

    return View(db.tblQuoteLog.Where(x => x.nID == id).FirstOrDefault());
}

編集 マイクが与えたアイデアからうまくいくように見えるロジックに変更を加えました(きちんとしていないかもしれませんが、小さいです)。

        //EOF is set to true if no records are found.
        var nextRecord = (from r in db.tblQuoteLog
                          orderby r.Quote_ID descending
                          where r.Quote_ID < id
                          select new
                          {
                              Quote_ID = r.Quote_ID,
                              EOF = false
                          }).Take(1).
                          FirstOrDefault() ?? new { Quote_ID = id, EOF = true };

        var previousRecord = (from r in db.tblQuoteLog
                              orderby r.Quote_ID ascending
                              where r.Quote_ID > id
                              select new
                              {
                                  Quote_ID = r.Quote_ID,
                                  EOF = false
                              }).Take(1).
                              FirstOrDefault() ?? new { Quote_ID = id, EOF = true };

        //Conditional Statements to manage navigation controls
        if ((nextRecord.EOF == true))
        {
            //Set value next button
            ViewBag.NextID = id;

            ViewBag.PreviousID = previousRecord.Quote_ID;
        }
        else if ((previousRecord.EOF == true))
        {
            ViewBag.NextID = nextRecord.Quote_ID;

            //Set value previous button
            ViewBag.PreviousID = id;
        }
        else
        {
            //Set value next button
            ViewBag.NextID = nextRecord.Quote_ID;

            //Set value previous button
            ViewBag.PreviousID = previousRecord.Quote_ID;
        }

匿名型を使用して、Linq クエリ内でエラー チェックが行われるようになりました。EOF (End of File) フラグを使用して、レコードが見つからない場合に ID が現在のレコードに設定され、EOF が true に設定されるようにします。

提案してくれてありがとう:)。

4

2 に答える 2

0

id -1; から上位 3 つを選択するのはどうでしょうか。

    public ViewResult Details(int id)
{
    var items = db.tblQuoteLog.OrderByDescending(x => x.LogDate).Where(x => x.Id >= (id - 1)).Take(3);
}
  • 結果に 3 つの項目がある場合、Previous、Next、および Current が表示されます。
  • 結果に 2 つの項目がある場合、あなたの ID は最後のページです
  • アイテムが 1 個または 0 個の場合、あなたの ID は無効です

もう少し考える必要があるかもしれませんが (たとえば、ID が 2 未満の場合)、それは潜在的なパスです

于 2012-11-28T16:39:38.720 に答える
0

これはかなりの挑戦だと思ったので、ラップトップを開いて試してみました。

私は最初の答えの道をたどりましたが、実際には3つではなく2つのクエリを持つために、くだらないコードの割り当てが生成されました。だから私はそれを単純化しました。Created列とId列の両方にインデックスを配置すると、これはすぐに機能するはずです。

PageServiceは、確認するクラスです。

class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer<MyDbContext>(null);

        var context = new MyDbContext(@"Data Source=.;Initial Catalog=Play;Integrated Security=True;");

        PageService service = new PageService(context);
        while (true)
        {
            Console.WriteLine("Please enter a page id: ");
            var pageId = Console.ReadLine();

            var detail = service.GetNavigationFor(Int32.Parse(pageId));

            if (detail.HasPreviousPage())
            {
                Console.WriteLine(@"Previous page ({0}) {1} {2}", detail.PreviousPage.Id, detail.PreviousPage.Name, detail.PreviousPage.Created);
            }
            else
            {
                Console.WriteLine(@"No previous page");
            }

            Console.WriteLine(@"Current page ({0}) {1} {2}", detail.CurrentPage.Id, detail.CurrentPage.Name, detail.CurrentPage.Created);


            if (detail.HasNextPage())
            {
                Console.WriteLine(@"Next page ({0}) {1} {2}", detail.NextPage.Id, detail.NextPage.Name, detail.NextPage.Created);
            }
            else
            {
                Console.WriteLine(@"No next page");
            }

            Console.WriteLine("");
        }


    }
}

public class PageService
{
    public MyDbContext _context;

    public PageService(MyDbContext context)
    {
        _context = context;
    }

    public NavigationDetails GetNavigationFor(int pageId)
    {
        var previousPage = _context.Pages.OrderByDescending(p => p.Created).Where(p => p.Id < pageId).FirstOrDefault();
        var nextPage = _context.Pages.OrderBy(p => p.Created).Where(p => p.Id > pageId).FirstOrDefault();
        var currentPage = _context.Pages.FirstOrDefault(p => p.Id == pageId);

        return new NavigationDetails()
        {
            PreviousPage = previousPage,
            NextPage = nextPage,
            CurrentPage = currentPage
        };
    }
}

public class NavigationDetails
{
    public Page PreviousPage { get; set; }
    public Page CurrentPage { get; set; }
    public Page NextPage { get; set; }

    public bool HasPreviousPage()
    {
        return (PreviousPage != null);
    }

    public bool HasNextPage()
    {
        return (NextPage != null);
    }
}

public class MyDbContext : DbContext
{
    public MyDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }

    public DbSet<Page> Pages { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new PageMap());
    }

}

public class PageMap : EntityTypeConfiguration<Page>
{

    public PageMap()
    {
        ToTable("t_Pages");

        Property(m => m.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(m => m.Name);
        Property(m => m.Created);
    }

}

public class Page
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
}

}

SQL コード

USE [Play]
GO

/****** Object:  Table [dbo].[t_Pages]    Script Date: 11/28/2012 20:49:34 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[t_Pages](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Created] [datetime] NULL,
 CONSTRAINT [PK_t_Page] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
于 2012-11-28T20:51:34.927 に答える