Действительно надеюсь, что кто-то может помочь, так как выкручивал мои волосы последние две ночи и не собирался быстро!и отчаянно пытаюсь запустить семейный проект, который я делаю без прибыли, и он быстро поглощает мое время, когда я пытаюсь использовать его для изучения некоторых новых технологий.
Кажется, это обычное делоКак я обнаружил, несколько похожих сообщений в ish на stackoverflow и т. д., но теперь, кажется, привели меня к работающему решению.
Я либо получаю ошибки, либо дублирую строки, поступающие в базу данных, моя упрощенная модель - одна ко многимотношения.Но я пытаюсь сохранить объект WebsiteUserSession в сеансе пользователя, чтобы сохранить попадание в базу данных при каждой загрузке страницы.
Модель:
public class WebsitePageTracking
{
[Key]
public long Id { get; set; }
public virtual WebsiteUserSession WebsiteUserSession { get; set; }
public DateTime DateTime { get; set; }
public string TrackUrl { get; set; }
}
public class WebsiteUserSession
{
[Key]
public long Id { get; set; }
public Guid Guid { get; set; }
public string IpAddress { get; set; }
public DateTime DateTime_Created { get; set; }
public DateTime DateTime_LastSessionStart { get; set; }
public virtual ICollection<WebsitePageTracking> WebsitePageTracking { get; set; }
}
Тогда мой код выглядит следующим образом, немногоболее сложный, но, надеюсь, получить идею.Обратите внимание, что текст данных хранится в HttpContext.Items, который был одним из предложений.
/// <summary>
/// public method for fetching and persisting website user session
/// </summary>
/// <returns></returns>
public static WebsiteUserSession GetWebsiteUserSession()
{
// set initial variables
Guid? websiteUserGuid = null;
string websiteUserIpAddress = HttpContext.Current.Request.UserHostAddress;
WebsiteUserSession websiteUserSession = null;
// first try and get from the session
if (HttpContext.Current.Session["WebsiteUserSession"] != null)
{
// load the website user session, and fetch out the guid
websiteUserSession = HttpContext.Current.Session["WebsiteUserSession"] as WebsiteUserSession;
websiteUserGuid = websiteUserSession.Guid;
// check to see if ip has changed, if so drop website user session
if (websiteUserSession.IpAddress != websiteUserIpAddress)
websiteUserSession = null;
}
else
{
// nothing so create brand new guid
websiteUserGuid = Guid.NewGuid();
}
// if we don't have one which came from the session then get the website user session using guid/ip
if (websiteUserSession == null)
websiteUserSession = GetWebsiteUserSession((Guid)websiteUserGuid, websiteUserIpAddress);
// if not stored in the session add that now
if (HttpContext.Current.Session["WebsiteUserSession"] == null)
HttpContext.Current.Session.Add("WebsiteUserSession", websiteUserSession);
// return back website user session object
return websiteUserSession;
}
/// <summary>
/// gets or creates a website user session record in the database
/// </summary>
/// <param name="guid">guid generated for the website user</param>
/// <param name="ipAddress">public ip address of website user</param>
/// <returns></returns>
private static WebsiteUserSession GetWebsiteUserSession(Guid guid, string ipAddress)
{
DataContext dataContext = HttpContext.Current.Items["DataContext"] as DataContext;
// try and fetch a user session from database
WebsiteUserSession websiteUserSession = dataContext
.WebsiteUserSessions
.Where(x => x.Guid == guid && x.IpAddress == ipAddress)
.SingleOrDefault();
if (websiteUserSession != null)
{
// if found update last session time
websiteUserSession.DateTime_LastSessionStart = DateTime.Now;
}
else
{
// create a new website user session
websiteUserSession = new WebsiteUserSession();
websiteUserSession.Guid = guid;
websiteUserSession.IpAddress = ipAddress;
websiteUserSession.DateTime_Created = websiteUserSession.DateTime_LastSessionStart = DateTime.Now;
dataContext.WebsiteUserSessions.Add(websiteUserSession);
}
// persist changes
dataContext.SaveChanges();
return websiteUserSession;
}
/// <summary>
/// log a stock page view to database
/// </summary>
/// <param name="stockId">id of stock being viewed</param>
public static void LogStockPageView(int stockId)
{
DataContext dataContext = HttpContext.Current.Items["DataContext"] as DataContext;
WebsiteUserSession websiteUserSession = GetWebsiteUserSession();
//dataContext.WebsiteUserSessions.Attach(websiteUserSession);
//dataContext.Entry(websiteUserSession).State = EntityState.Unchanged;
WebsitePageTracking pageTrack = new WebsitePageTracking();
pageTrack.WebsiteUserSession = websiteUserSession;
pageTrack.DateTime = DateTime.Now;
pageTrack.TrackUrl = HttpContext.Current.Request.Url.ToString();
dataContext.Entry(client).State = EntityState.Unchanged;
dataContext.Entry(website).State = EntityState.Unchanged;
dataContext.Entry(websiteUserSession).State = EntityState.Unchanged;
//dataContext.Entry(websiteUserSession.WebsitePageTracking).State = EntityState.Detached;
//dataContext.WebsiteUserSessions.Attach(pageTrack.WebsiteUserSession);
dataContext.WebsitePageTracking.Add(pageTrack);
//dataContext.Entry(pageTrack.WebsiteUserSession).State = EntityState.Unchanged;
dataContext.SaveChanges();
}
В основном, что происходит, когда кто-то просматривает страницу, вызывается LogStockPageView (), который, в свою очередь, получает объект WebsiteUserSession либо из сеанса, база данных или создает новый.Затем сущность WebsitePageTracking добавляется в базу данных с привязкой к WebsiteUserSession.
Вы можете увидеть все закомментированные строки попыток, чтобы заставить это работать, но я либо получаю ошибки, либо вставляю много дублирующихся строк: (
Одна из таких ошибок заключается в следующем: «Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом.".
Пожалуйста, кто-нибудь может увидеть, где я 'я ошибаюсь или даже предлагаю лучшие решения? действительно пытаюсь работать с EF, но изо всех сил: (
Спасибо, Карл