2012-08-31 56 views
1

我想統計用戶觀看產品的次數。如何計算用戶的視圖?

產品具有在整數類型的觀看次數屬性,在詳細信息視圖中,我增加的觀看次數

public ActionResult Details(int id) 
    { 
    ... 
    product.ViewCount = product.ViewCount + 1; 
    db.SaveChanges(); 
    return View(product); 
    } 

但在每次刷新,觀看次數的增加而增加。

我應該怎麼做ViewCount在每個用戶會話中增加1次?

或其他方式,正確的標記,任何鏈接,請。

回答

6

您可以使用cookie。

var productId = 1; 


if (Request.Cookies["ViewedPage"] != null) 
{ 
    if (Request.Cookies["ViewedPage"][string.Format("pId_{0}",productId)] == null) 
    { 
     HttpCookie cookie = (HttpCookie)Request.Cookies["ViewedPage"]; 
     cookie[string.Format("pId_{0}",productId)] = "1"; 
     cookie.Expires = DateTime.Now.AddDays(1); 
     Response.Cookies.Add(cookie); 

     db.Execute("UPDATE Products SET ViewCount = ViewCount + 1 WHERE ProductId = @id", new { id = productId }); 
     db.SaveChanges(); 
    } 
} 
else 
{ 
    HttpCookie cookie = new HttpCookie("ViewedPage"); 
    cookie[string.Format("pId_{0}",productId)] = "1"; 
    cookie.Expires = DateTime.Now.AddDays(1); 
    Response.Cookies.Add(cookie); 

    db.Execute("UPDATE Products SET ViewCount = ViewCount + 1 WHERE ProductId = @id", new { id = productId }); 
    db.SaveChanges(); 
} 
+0

你可以重構它以減少重複的代碼。 – Dai

+0

你是對的,但這是示例代碼 –

2

您的代碼不是線程安全的:如果兩個用戶同時訪問該頁面,則ViewCount將增加1而不是2(因爲該值由DB消費者而不是DB本身增加)。您可以通過直接運行SQL UPDATE Products SET ViewCount = ViewCount + 1 WHERE ProductId = @id來解決此問題。您的DBMS將提供併發保護。

總之,要防止觀看次數在同一會議上通過其他視圖遞增只使用存儲在會話HashSet的,就像這樣:

public ActionResult Details(Int32 id) { 

    HashSet<Int32> productsSeen = (HashSet<Int32>)Session["ProductsSeen"]; 
    if(productsSeen == null) { 
     Session["ProductsSeen"] = productsSeen = new HashSet<Int32>(); 
    } 

    if(!productsSeen.Contains(id)) { 

     db.Execute("UPDATE Products SET ViewCount = ViewCount + 1 WHERE ProductId = @id", new { id = id }); // psuedocode. This isn't a real EF construct. 
     db.SaveChanges(); 
    } 

    return View(product); 
} 
+0

有沒有db.Execute()。我將其替換爲「product.ViewCount = product.ViewCount + 1;」。但是,每次刷新計數都會增加(( –

3

我建議你創造一些動作過濾器來跟蹤它。

public class TrackFilter: IResultFilter 
{ 
    public void OnResultExecuting(ResultExecutingContext filterContext) 
    { 

    } 

    public void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
    // do a database call and update the count 
    } 
} 

[Track] 
public ActionResult Details(int id) 
{ 
} 

您也可以參考這個thread也有更多的想法。

+0

啊,是的,屬性。好主意。 – Dai

0
model.ViewCount = model.ViewCount + 1; 

_context.Entry(model); 

_context.SaveChanges(); 

return View(model); 
0

這提高戴代碼。您必須添加productsSeen.Add(id);在第二個如果陳述

public ActionResult Details(Int32 id) { 

    HashSet<Int32> productsSeen = (HashSet<Int32>)Session["ProductsSeen"]; 
    if(productsSeen == null) { 
     Session["ProductsSeen"] = productsSeen = new HashSet<Int32>(); 
    } 

    if(!productsSeen.Contains(id)) { 
     productsSeen.Add(id); 
     db.Execute("UPDATE Products SET ViewCount = ViewCount + 1 WHERE ProductId = @id", new { id = id }); // psuedocode. This isn't a real EF construct. 
     db.SaveChanges(); 
    } 

    return View(product); 
} 
+0

歡迎來到Stack Overflow。人們,如果你解釋爲什麼增加這條線會有所幫助,這將更加完整。 – FluffyKitten