【问题标题】:Error with entities that do not expose foreign key properties for their relationships不为其关系公开外键属性的实体出错
【发布时间】:2011-03-23 16:43:25
【问题描述】:

我花了一些时间来构建我的领域模型(使用 EF CTP5 代码优先),现在我想我应该通过一些测试数据看看是否一切正常。不幸的是,我的应用程序似乎加载了除了运行时之外不会被捕获的错误,因为一切都可以完美编译。无论如何,我不断收到以下错误:

保存时出错 不暴露外国的实体 他们的关键属性 关系。

这是内部异常:

"INSERT 语句与 FOREIGN KEY 约束 \"Item_ItemStatus\"。冲突 发生在数据库“CFShawe”中, 表 \"dbo.ItemStatus\",列 'Id'。\r\n语句已被 终止。”

我不知道为什么会这样。我怀疑这可能是由我在 Seed() 方法中加载数据库的所有静态内容的初始化程序类引起的。所以我评论了我添加 ItemStatuses 的部分,但我仍然遇到同样的错误。此外,我应该在编译时得到这个,而不是在运行时,不是吗?

下面是 ItemStatus 类和我的部分测试数据:

public class ItemStatus
{
 public int Id { get; set; }
 public string Description { get; set; }
 public ICollection<Item> Items { get; set; }
}

//Test data inside the Index() method of the ItemsController
var item2 = new Item
  {
   Title = "iPhone 4",
   Description = "Lorem Ipsum is simply",
   StartingPrice = 400f,
   User = user2,
   Status = 1,
   EndDate = DateTime.Now.AddDays(10),
   StartDate = DateTime.Now,
   BidIncrement = 3f,
   Bids = new List<Bid>(),
   Comments = new List<Comment>(),
   //ItemStatus = _itemsService.GetItemStatusById(1),    
   ViewingUsers = new List<User>(),
   WatchingUsers = new List<User>(),
   Tags = new List<Tag>()
  };
  //here's where I save the data to the database
  var category = _categoryService.GetChildByName(categoryName);
  category.Items.Add(item2);
  _categoryService.Save();

更新:(由 Slauma 要求)

public class Item
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public float StartingPrice { get; set; }
    public float? BidIncrement { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public int Status { get; set; }
    [ForeignKey("Status")]
    public virtual ItemStatus ItemStatus { get; set; }
    public virtual Address PickupAddress { get; set; }
    public virtual User User { get; set; }
    public virtual ChildCategory Category { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<Image> Images { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
    public virtual ICollection<User> WatchingUsers { get; set; }
    public virtual ICollection<User> ViewingUsers { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
    //public virtual ItemRating Rating { get; set; }

    public bool IsValidBidAmount(int amount)
    {
        if (amount <= this.Bids.Max(a => a.Amount))
            return false;

        return true;
    }

    public bool IsClosed()
    {
        if (this.ItemStatus.Id.Equals(3))
            return true;
        return false;
    }

    public bool IsPending()
    {
        if (ItemStatus.Id.Equals(2))
            return true;
        return false;
    }

    public bool IsPublished()
    {
        if (ItemStatus.Equals(1))
            return true;
        return false;
    }

    public int WinnerId()
    {
        if(IsClosed())
        {
            User highestBidder = null;
            foreach (Bid b in Bids)
            {
                if (b.Amount.Equals(HighestBid()))
                    highestBidder = b.User;
            }
            if (highestBidder != null) return highestBidder.Id;
        }
        return 0;
    }

    public float HighestBid()
    {
        return Bids.Max(u => u.Amount);
    }

    public string MainImageLink()
    {
        var mainImage = Images.Single(i => i.Rank.Equals(0));
        return mainImage.Path;
    }

    public string FirstTag()
    {
        return Tags.First().Title;
    }
}

更新 2:

public class UnitOfWork : IUnitOfWork
{
    private readonly IDatabaseFactory _databaseFactory;
    private DbContext _context;
    public UnitOfWork(IDatabaseFactory dbFactory)
    {
        _databaseFactory = dbFactory;
    }

    protected DbContext DataContext
    {
        get
        {
            return _context ?? (_context = _databaseFactory.GetDbContext());
        }
    }

    public void Commit()
    {
        DataContext.SaveChanges();
    }
}

public class EfDatabaseFactory : IDisposable, IDatabaseFactory
{
    private SharweEntities _dbContext;


    public DbContext GetDbContext()
    {
        return _dbContext ?? (_dbContext = new SharweEntities());
    }

    public System.Data.Objects.ObjectContext GetObjectContext()
    {
        return _dbContext.ObjectContext;
    }

    public void Dispose()
    {
        if (_dbContext != null)
            _dbContext.Dispose();
    }
}

对这件事有什么想法吗?提前致谢。

【问题讨论】:

  • 您在哪里/如何管理您的 DBContext?
  • 您展示了很多代码,但没有任何与您的问题相关的代码。除了ItemStatus 和创建Item 和ItemStatus 的代码,将其添加到DbContext 并调用SaveChanges 之外,Item 类也会很有帮助。此外,如果您在模型类属性上放置了属性,或者您是否使用 Fluent API 以及如何自定义模型。并删除这个 Lore ipsum 和图像的东西......
  • @Derek Beattie:我正在使用 UnitOfWork 来管理 DbConext。在上面的 sn-p (我已经编辑过)中,我调用 categoryService 上的 Save() 方法,该方法调用 unitOfWork.Commit() 反过来又调用 context.SaveChanges()
  • @Slauma:我已经更新了我的帖子并添加了我已经拥有的代码。您认为问题出在我使用 DataAnnotations 标记为 FK 的 Status 属性上吗?
  • @Kassem:你的 FK 属性说,int StatusItemStatus 表的 FK。由于它不可为空,因此它是必需的关系。在保存Item2 之前设置Status=1。所以,问题:数据库中是否有ItemStatus 行与Id = 1

标签: c# .net entity-framework entity-framework-4 ef-code-first


【解决方案1】:

我认为错误表明您的数据库中没有 ID = 1 的 ItemStatus 记录。

【讨论】:

猜你喜欢
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-19
  • 2014-05-17
  • 1970-01-01
  • 2012-01-17
相关资源
最近更新 更多