English 中文(简体)
添加插入新实体和设置对其他实体的引用时违反PK(其他实体)
原标题:PK Violation (of other entity) when adding inserting new entity and setting a reference to other entity

我使用的是Entity Framework 4.3,在创建新实体时,我试图通过设置导航属性来引用现有实体,但是当我调用save EF时,它抱怨我设置导航属性的表中存在PK违规(即它正在创建新记录而不是引用!)。

我如何附加到现有的POCO,而不是引用它并让EF尝试创建新的数据库记录(但不仅仅是使用ID,理想情况下我想引用来自另一个查询的实际实体)?

提前感谢,

克里斯

public class BusinessUnit
{
    public int BusinessUnitID { get; set; }
    public ExternalPlugin AccountsDataSourceModule { get; set; }
    public ExternalPlugin OptionalContactsDataSourceModule { get; set; }
}

public BusinessUnit NewBusinessUnit(string name, ExternalPlugin accountsModuleId = null, ExternalPlugin contactsModuleId = null)
{
    IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork();

    BusinessUnit unit = new BusinessUnit();
    unit.CompanyName = name;
    unit .AccountsDataSourceModule = accountsModuleId; // this causes a problem
    unit .OptionalContactsDataSourceModule = contactsModuleId; // as does this
    unitOfWork.BusinessUnitRepository.Insert(unit);

    unitOfWork.Save();
    return unit;
}
最佳回答

您必须将现有实体附加到上下文中:

BusinessUnit unit = new BusinessUnit();
unit.CompanyName = name;

unitOfWork.ExternalPluginRepository.Attach(accountsModuleId);
unitOfWork.ExternalPluginRepository.Attach(contactsModuleId);

unit.AccountsDataSourceModule = accountsModuleId;
unit.OptionalContactsDataSourceModule = contactsModuleId;
unitOfWork.BusinessUnitRepository.Insert(unit);

…其中unitOfWork.ExternalPluginRepository。附加(外部插件插件)必须执行以下操作:

context.ExternalPlugins.Attach(plugin);

我希望所有存储库都使用相同的上下文实例Attach告诉EF插件已经存在于数据库中,并避免插入这些实体。

编辑

如果您收到错误消息。。。

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

…这意味着您有一个实体同时附加到多个上下文实例。在大多数情况下,你可以通过在不再需要的时候处理上下文来避免这种情况。您的代码示例不符合此良好做法。它应该看起来像这样:

public BusinessUnit NewBusinessUnit(string name,
    ExternalPlugin accountsModuleId = null,
    ExternalPlugin contactsModuleId = null)
{
    using (IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork())
    {
        BusinessUnit unit = new BusinessUnit();
        unit.CompanyName = name;

        unitOfWork.ExternalPluginRepository.Attach(accountsModuleId);
        unitOfWork.ExternalPluginRepository.Attach(contactsModuleId);

        unit.AccountsDataSourceModule = accountsModuleId;
        unit.OptionalContactsDataSourceModule = contactsModuleId;
        unitOfWork.BusinessUnitRepository.Insert(unit);

        unitOfWork.Save();

        return unit;
    }
}

使用块的末尾,会自动调用unitOfWorkdisposalIDisposable派生IUnitOfWorkUnitOfWork<-code>类中实现它:

public interface IUnitOfWork : IDisposable
{
    // ...
}

public class ConcreteUnitOfWork : IUnitOfWork, IDisposable
{
    private MyDbContext _context;
    // I assume that you have a member for the DbContext in this class
    // ...

    // implementation of IDisposable
    public void Dispose()
    {
        if (_context != null)
            _context.Dispose();
    }
}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...