2012-03-28 65 views
0

我在WCF上有一個C#REST服務,它位於SQL 2008上的EF 4.2框架的頂部。有幾個實體,但重要的兩個是Trips及其子項PlacesOfInterest。爲什麼向我的實體框架添加一個子元素嘗試插入一個新的父元素?

下面是表:

-- Creating table 'Trips' 
CREATE TABLE [dbo].[Trips] (
[Id] uniqueidentifier NOT NULL, 
[Name] nvarchar(max) NOT NULL, 
[ArrivalDate] datetime NULL, 
[DepartureDate] datetime NULL, 
[WhereTo] nvarchar(max) NOT NULL, 
[CreatedDate] datetime NULL, 
[UpdatedDate] datetime NULL, 
[Album] nvarchar(max) NOT NULL, 
[UserToken] nvarchar(max) NOT NULL, 
[WallPostId] nvarchar(max) NOT NULL 
); 
GO 

-- Creating table 'PlacesOfInterest' 
CREATE TABLE [dbo].[PlacesOfInterest] (
[Id] uniqueidentifier NOT NULL, 
[PhoneNumber] nvarchar(max) NOT NULL, 
[SmallPicture] nvarchar(max) NOT NULL, 
[LargePicture] nvarchar(max) NOT NULL, 
[HostId] nvarchar(max) NOT NULL, 
[HostName] nvarchar(max) NOT NULL, 
[Address1] nvarchar(max) NOT NULL, 
[Address2] nvarchar(max) NOT NULL, 
[Address3] nvarchar(max) NOT NULL, 
[City] nvarchar(max) NOT NULL, 
[State] nvarchar(max) NOT NULL, 
[Zip] nvarchar(max) NOT NULL, 
[Latitude] bigint NOT NULL, 
[Longitude] bigint NOT NULL, 
[URL] nvarchar(max) NOT NULL, 
[MapUrl] nvarchar(max) NOT NULL, 
[Hours] nvarchar(max) NOT NULL, 
[Name] nvarchar(max) NOT NULL, 
[PageId] nvarchar(max) NOT NULL, 
[Trip_Id] uniqueidentifier NOT NULL, 
[Category_Id] int NULL 
); 
GO 

這裏是我的POCO模型。

public class Trip 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public DateTime ArrivalDate { get; set; } 
    public DateTime DepartureDate { get; set; } 
    public string WhereTo { get; set; } 
    public DateTime CreatedDate { get; set; } 
    public DateTime UpdatedDate { get; set; } 
    public string Album { get; set; } 
    public List<PlaceOfInterest> PlacesOfInterest { get; set; } 
    public List<Photo> Photos { get; set; } 
    public string UserToken { get; set; } 
    public string WallPostId { get; set; } 
} 

public class PlaceOfInterest 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public string PhoneNumber { get; set; } 
    public string Address1 { get; set; } 
    public string Address2 { get; set; } 
    public string Address3 { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public string Zip { get; set; } 
    public long Latitude { get; set; } 
    public long Longitude { get; set; } 
    public string SmallPicture { get; set; } 
    public string LargePicture { get; set; } 
    public string HostId { get; set; } 
    public string HostName { get; set; } 
    public string URL { get; set; } 
    public string MapUrl { get; set; } 
    public string Hours { get; set; } 
    public Category Category { get; set; } 
    public List<Photo> Photos { get; set; } 
    public List<Checkin> Checkins { get; set; } 
    public List<PoiAttribute> PoiAttributes { get; set; } 
    public Guid TripId { get; set; } 
    public string PageId { get; set; } 
    [IgnoreDataMember] 
    public Trip Trip { get; set; } 
} 

當我添加一個新的PlaceOfInterest時,實體框架試圖插入一個列表,並且我得到一個重複的鍵錯誤。

public static Guid Create(string tripId, Model.PlaceOfInterest instance) 
    { 
     var context = new Model.POCOTripContext(); 
     var cleanPoi = new Model.PlaceOfInterest(); 
     cleanPoi.Id = Guid.NewGuid(); 
     cleanPoi.Address1 = instance.Address1; 
     cleanPoi.Address2 = instance.Address2; 
     cleanPoi.Address3 = instance.Address3; 
     cleanPoi.City = instance.City; 
     cleanPoi.HostId = instance.HostId; 
     cleanPoi.HostName = instance.HostName; 
     cleanPoi.Hours = instance.Hours; 
     cleanPoi.LargePicture = instance.LargePicture; 
     cleanPoi.Latitude = instance.Latitude; 
     cleanPoi.Longitude = instance.Longitude; 
     cleanPoi.MapUrl = instance.MapUrl; 
     cleanPoi.Name = instance.Name; 
     cleanPoi.PageId = instance.PageId; 
     cleanPoi.PhoneNumber = instance.PhoneNumber; 
     cleanPoi.SmallPicture = instance.PhoneNumber; 
     cleanPoi.State = instance.State; 
     cleanPoi.Trip = Library.Trip.Get(new Guid(tripId)); 
     cleanPoi.URL = instance.URL; 
     cleanPoi.Zip = instance.Zip; 
     context.PlacesOfInterest.AddObject(cleanPoi); 
     context.SaveChanges(); 
     return cleanPoi.Id; 
    } 

我不希望它插入那個行程,我只是想要它更新數據庫中的TripId列。我究竟做錯了什麼?

回答

2

很可能這條線的問題是:

cleanPoi.Trip = Library.Trip.Get(new Guid(tripId)) 

如果Get負載從DB行程則明顯加載它在其他方面比context。你應該使用相同的上下文。編寫它很醜陋,如:Get(context, new Guid(tripId)),然後使用該注入的上下文。

如果Get剛剛創建的Tripnew Trip { ... })的情況下,你必須將其附加到上下文:

cleanPoi.Trip = Library.Trip.Get(new Guid(tripId)) 
context.Trips.Attach(cleanPoi.Trip); 

但是你們都不必因爲你顯然有一個外鍵屬性。然後,這是不夠的:

cleanPoi.TripId = new Guid(tripId); 
+0

不應該這個'context.PlacesOfInterest.Attach(cleanPoi.Trip);'是'context.Trips.Attach(cleanPoi.Trip);'? – cadrell0 2012-03-28 20:50:39

+0

@ cadrell0:當然可以:)謝謝,現在已經修好了。 – Slauma 2012-03-28 20:53:36

+0

這個工作,但是當我到達SaveChanges時,數據庫插入炸彈:{「不能將NULL值插入到'Id'列'PersonalAssistant.dbo.PlacesOfInterest'列中;列不允許空值,INSERT失敗。\ r \ n該語句已被終止。「} ID字段填充在cleanPoi和上下文對象中。想法? – 2012-03-29 00:05:20

1

您應該從您保存的相同DataContext獲取cleanPoi.Trip。

1

在你創建的方法,你所得到的旅行和PointOfInterest的行程設置跳開你抓着。這有兩個問題:

  1. 您不處理Trip不存在的情況。
  2. 您正在設置對DbContext中的ChangeTracker捕獲的行程的引用。

您可以通過簡單的設置TRIPID的PointOfInterest對象上,然後包裹在一個try/catch處理異常,如果外鍵不存在,EF將引發整個事情解決這兩個問題。

此外,您需要深入研究InnerException的細節,因爲返回的Exception將具有關於問題的具體信息。問題可能在於其中一個GUID = Guid.Empty,並且您要插入的GUID也有一個空的GUID。這將顯示完全不同的問題的證據。