지난 2 일 동안 내 머리카락을 찢어 놓고 아무런 조치도 취하지 않아서 누군가가 도울 수 있기를 바랍니다. 필사적으로 제가 새로운 기술을 배우기 위해 그것을 사용하려고 할 때, 이익을 얻지 않고 빠르게 시간을 먹어가는 가족 프로젝트를 필사적으로 시도하고 있습니다.EF 4.3 1 대 다수 저장 오류 또는 중복 행
이것은 stackoverflow 등등에 몇몇 유사한 ish 포스트를 찾아 내고 그러나 지금 작동 해결책에 안내 한 것을 보이는 일반적인 문제점다는 것을 보인다.
데이터베이스에 오류나 중복 행이 생기면 단순화 된 모델이 일대 다 관계입니다. 하지만 모든 페이지로드시 데이터베이스 히트를 저장하기 위해 사용자 세션에 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; }
}
다음과 같이 그리고 내 코드는 좀 더 복잡하지만 희망 아이디어를 얻을. datacontext는 하나의 제안 인 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();
}
는 기본적으로 무엇을 어떻게해야 할 것은 누군가가 차례로 중 세션, 데이터베이스에서 WebsiteUserSession 엔티티를 얻을하거나 새로 생성 호출되는 페이지 LogStockPageView()를 탐색합니다. 그런 다음 WebsitePageTracking 엔티티가 WebsiteUserSession에 대한 연결로 데이터베이스에 추가됩니다.
당신은이 작업을 얻기 위해 시도의 모든 주석 라인을 볼 수 있습니다,하지만 난 오류 또는 삽입되는 :(
하나는 이러한 오류는 동일한 키가 이미이 "목적은 중복 행을 많이 얻을 중 ObjectStateManager에서 동일한 키가있는 여러 객체를 추적 할 수 없습니다. "
내가 잘못하고있는 곳을 보거나 더 나은 해결책을 제안 할 수 있습니까? 실제로 EF로 가려고하는데 어려움을 겪으십시오. (
감사합니다. Carl
와우, 그 자리에 좋은 설명이 있습니다 ... 다른 엔티티를 참조하는 샘플 코드에 대해 유감스럽게 생각합니다. 실수를 간략화했지만 일부 비트를 빼는 것을 잊었습니다. 어쨌든 당신의 제안 된 변경 사항을 만들었고 작동합니다 !! 그리고 물건은 지금 훨씬 명확하다. .. 뉴질랜드에서의 과거의 자정이다. 그래서 취침 시간에 갔어야했다. 그러나 당신의 제안을 시험해 보는 데 흥미가 있었다. .. 내일 그들에게 다시 상세하게 갈 것이고, 나의 프로젝트와 함께 계속 될 것이다. 백만!! – user1259167