【问题标题】:Entity Framework with WCF POCOs Referential Integrity Issue具有 WCF POCO 的实体框架参照完整性问题
【发布时间】:2012-09-17 11:18:21
【问题描述】:

我有一个相当简单的场景,我似乎无法获得正确的逻辑。我正在使用带有 POCO 的 WCF 服务来读取数据并将数据写入数据库。我有一个关键字表,其中有一个外键 UserID 链接到 UserProfile 表。我正在添加和修改关键字集合,但是当我尝试在 GetKeywords 方法中包含 UserProfile 然后进行一些更改并调用 StoreKeywords 方法时,我遇到了参照完整性问题。如果我不包含 UserProfiles,我可以添加和更新没有问题。我使用了支持 WCF 的 POCO 生成器,并修改了 T4 以删除虚拟并使用 FixupCollections。

任何帮助将不胜感激。提前致谢。

GetKeywords 服务:

    public class Service : IService
    {
    public List<Keyword> GetKeywords()
    {
        var context = new myDBEntities();

        var query = from c in context.Keywords
                        .Include("UserProfile")
                    select c;

        //var query = from c in context.Keywords.Take(100)
        //            select c;

        return query.ToList();

    }

调用 GetKeywords 的客户端代码进行一些更改,然后调用 StoreKeywords:

    public partial class MainWindow : Window
{
    ObservableCollection<Keyword> keylist;
    public MainWindow()
    {
        InitializeComponent();
        PopulateGrid();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        myServiceClient client = new myServiceClient();

        List<Keyword> updates = new List<Keyword>();

        foreach (Keyword keyword in keylist)
        {
            if (keyword.State == State.Added)
            {
                keyword.CreationDate = DateTime.Now;
                updates.Add(keyword);
            }

            if (keyword.State == State.Modified)
            {
                keyword.EditDate = DateTime.Now;
                if (keyword.IsVoid == false) keyword.VoidDate = null;
                if (keyword.IsVoid == true) keyword.VoidDate = DateTime.Now;
                updates.Add(keyword);
            }
        }

        client.StoreKeywords(updates.ToArray());

        foreach (var kw in keylist)
        {
            kw.State = State.Unchanged;
        }

        PopulateGrid();
        gridControl1.RefreshData();
    }

    private void PopulateGrid()
    {
        myServiceClient client = new myServiceClient();

        keylist = new ObservableCollection<Keyword>(client.GetKeywords());

        gridControl1.ItemsSource = keylist;

    }

StoreKeywords 服务:

public string StoreKeywords(List<Keyword> keywords)
    {
        try
        {
            using (var context = new myDBEntities())
            {
                context.ContextOptions.LazyLoadingEnabled = false;

                foreach (Keyword kw in keywords)
                {

                        context.Keywords.Attach(kw);
                        context.ObjectStateManager.ChangeObjectState(kw, StateHelpers.GetEquivalentEntityState(kw.State));

                }
                context.SaveChanges();
                return "";
            }
        }
        catch (Exception ex)
        {

            return ex.Message;
        }

    }

【问题讨论】:

  • 总是告诉哪里(在哪一行代码)发生了异常。还有您在下面的评论中提到的例外情况。
  • 异常发生在 context.Keywords.Attach(kw);但这是由于 GetKeywords 方法包括 UserProfile

标签: wcf entity-framework poco


【解决方案1】:

在互联网上搜索后,我找到了我的问题here 的答案,这对我来说根本不明显。问题出在 GetKeyword() 方法中,因为它试图跟踪合并。新的 GetKeywords() 方法:

public List<Keyword> GetKeywords()
    {
        var context = new InstanexDBEntities();
        context.Keywords.MergeOption = MergeOption.NoTracking; 

        var query = from c in context.Keywords
                        .Include("UserProfile").Take(100)
                    select c;

        return query.ToList();


    }

【讨论】:

  • 现在当我尝试一次修改多个关键字时仍然遇到问题,这告诉我...(ObjectStateManager 中已经存在具有相同键的对象。ObjectStateManager 无法跟踪多个具有相同键的对象。)
  • 事实证明,真正的问题是尝试 .include 父 UserProfile 以及 child 关键字对 Entity Framework 并没有真正意义。从 GetKeywprds 方法中删除 Userprofiles,然后在客户端调用另一个 getUserProfiles 是更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多