簡體   English   中英

為什么在我的實體框架中添加子元素會嘗試插入新的父元素?

[英]Why does adding a child element to my entity framework try and insert a new parent?

我在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列。 我究竟做錯了什么?

這行很可能是問題所在:

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

如果Get加載從DB行程則明顯加載它在另一種情況下比context 您應該使用相同的上下文。 要寫起來很丑,就像這樣: Get(context, new Guid(tripId))然后使用那個注入的上下文。

如果Get僅創建Trip的實例( new Trip { ... } ),則必須將其附加到上下文:

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

但是你們所有人都不需要這樣做,因為您顯然具有外鍵屬性。 這就足夠了:

cleanPoi.TripId = new Guid(tripId);

您應該從要保存的同一DataContext中獲取cleanPoi.Trip。

在您的Create方法中,您將獲得Trip並將PointOfInterest的Trip設置為您抓取的那個Trip。 這有兩個問題:

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

您可以通過簡單地在PointOfInterest對象上設置TripId,然后將整個內容包裝在Try / Catch中來解決這兩個問題,該Try / Catch處理如果外鍵不存在則EF拋出的異常。

另外,您還需要深入研究InnerException詳細信息,因為返回的Exception將會提供有關問題所在的非常具體的信息。 問題可能在於其中一個GUID = Guid.Empty,而您要插入的GUID也具有空的GUID。 那將顯示出一個完全不同的問題的證據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM