C#和EF 4.0:在处理外部表时感到困惑 [英] C# & EF 4.0: confusing in handling foreign tables

查看:32
本文介绍了C#和EF 4.0:在处理外部表时感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对这个标题我很抱歉,想不出更好的标题.任何修改,不胜感激!

I'm very sorry for the title, can't figure out a better one. Any amendment is greatly appreciated!

说我有这些表:

Header(id int identity(1,1), Date datetime, ...) 

Detail(id int identity(1,1), HeaderID int, MaterialID nvarchar(24), Quantity float, AccountID nvarchar(20), Amount float)

Ledger(HeaderID, AccountID nvarchar(20), Amount float) 

InventoryTransactionDetail(HeaderID, MaterialID nvarchar(24), Quantity float)

这是它的工作方式:

  • 标题包含凭证的一般信息

  • Header contains general information of a voucher

明细包含凭证的明细记录

Detail contains voucher's detail records

然后我们将分析Detail的记录并为Ledger和库存生成数据

We will then analyze Detail's record and produce data for Ledger and Inventory

例如:

Insert into Header(Date, ...) values (getdate(), ...)

Assuming the newly created header ID is 1 

Insert into Detail(HeaderID, MaterialID, Quantity, AccountID, Amount) 
    values(1, 'MAT1', 50, '1561', 500000)

After analyzing, we have Ledger and InventoryTransactionDetail's records: 

Insert into Ledger(HeaderID, AccountID, Amount) 
    values(1, '1561', 500000)

Insert into InventoryTransactionDetail(HeaderID, MaterialID, Quantity) 
    values(1, 'MAT1', 50)

因此,如果对凭证进行了任何更改,我将:

So if there is any changes was made on the voucher, i will :

  • 更新标题和详细信息
  • 从Ledger和Inventory中删除,并将新的分析记录插入其中

听起来很简单,对吧?我可以一目了然地使用T-sql来实现此目的,但是使用EF做到这一点给了我一个噩梦,我不断收到错误信息,我不知道为什么以及如何解决它!

Sound simple, right? I can achieve this using T-sql in just a glance, but doing this using EF is giving me a nightmare, i keep getting errors i can't figure out why and how to fix it!

所以我想问的是,我这样做正确吗?

So what i want to ask is, am i doing this the right way?

顺便说一句,这是我遇到的错误之一:

By the way, this is one of the errors i'm getting :

发生参照完整性约束违规:该属性定义引用约束的值不一致关系中主要对象和从属对象之间的关系.

A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

错误行(最后一行之前的行:Attach(VH)):

Line of error (the line before the last : Attach(VH) ) :

    using (var context2 = new GModel())
    {
        List<Ledger> AJToCheck = (from a in context2.Ledger where a.VHID == VH.ID select a).ToList();
        foreach (Ledger DetailToCheck in AJToCheck)
        {
            context2.DeleteObject(DetailToCheck);
        }

        List<ITDetail> ITToCheck = (from a in context2.ITDetail where a.VHID == VH.ID select a).ToList();
        foreach (ITDetail DetailToCheck in ITToCheck)
        {
            context2.DeleteObject(DetailToCheck);
        }

        context2.SaveChanges();
    }

    using (var context = new GModel())
    {
        if (VH.ID == 0 || VH.ID == null)
        {
            VH.State = State.Added;
            context.VoucherHeader.AddObject(VH);
        }
        else
        {
            VH.State = State.Modified;

            int counterID = -1;

            foreach (var voucherDetail in VH.VoucherDetail)
            {
                if (voucherDetail.ID == 0)
                {
                    counterID--;
                    voucherDetail.State = State.Added;
                    voucherDetail.ID = counterID;
                }
                else voucherDetail.State = State.Modified; 
            }

            counterID = -1;

            foreach (var Ledger in VH.Ledger)
            {
                counterID--;
                Ledger.State = State.Added;
                Ledger.ID = counterID;
            }

            counterID = -1;

            foreach (var itDetail in VH.ITDetail)
            {
                counterID--;
                itDetail.State = State.Added;
                itDetail.ID = counterID;
            }

            context.VoucherHeader.Attach(VH);
            context.ObjectStateManager.ChangeObjectState(VH, StateHelpers.GetEquivalentEntityState(VH.State));

推荐答案

这似乎比需要的复杂得多.

This appears to be much more complex than it needs to.

当一对多关系的许多部分中的实体使用与父对象不同的外键附加时,通常会发生此错误.

This error generally occurs when the entity in the many part of a one to many relationship is being attached with a foreign key different from the parent object.

在您所显示的SQL示例中,您插入到从属表中并仅设置了listenerID,但是在所有EF示例中,您为所有导航属性的ID属性分配了负数吗?

In your case the SQL examples you show, you insert into the dependent tables and only set the hearderID, but in all your EF examples you assign negative numbers to the ID properties of all your navigation properties?

要重复使用SQL,最好直接使用VH,而不要尝试操纵导航属性.

To repeat what you have with SQL you would be better off just going straight to the attach of your VH rather than attempting to manipulate the navigation properties.

当附加了VH时,将自动添加(插入)图形中不存在的任何导航属性(ID == 0).无需将VH及其导航属性都标记为已修改,这可能会导致问题.

When VH is attached, any of the navigation properties in the graph that didn't exist (IDs == 0) will be automatically added (inserted). Your marking both the VH and its navigation properties as modified is unnecessary, and likely contributes to your problem.

尝试以下方法:

    if (VH.ID == 0 || VH.ID == null)
    {
        VH.State = State.Added;
        context.VoucherHeader.AddObject(VH);
    }
    else
    {
        VH.State = State.Modified;
        context.VoucherHeader.Attach(VH);
        context.ObjectStateManager.ChangeObjectState(VH, StateHelpers.GetEquivalentEntityState(VH.State));
    }

还可以查看 http://msdn.microsoft.com/en-us/magazine/dn166926.aspx 用于该版本的EF

Also take a look at http://msdn.microsoft.com/en-us/magazine/dn166926.aspx for that version of EF

这篇关于C#和EF 4.0:在处理外部表时感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆