EntityFramework Core-复制实体并将其放回数据库 [英] EntityFramework Core - Copying an entity and placing it back into the database

查看:290
本文介绍了EntityFramework Core-复制实体并将其放回数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在制作实体副本,根据用户输入对其进行一些更改,然后将其重新插入数据库的最佳实践?

Is there a best practice for doing a copy of an entity, making some changes to it based on user input, and then re-inserting it into the database?

其他一些Stackoverflow线程提到,即使数据库中存在相同的主键,EF也会为您处理插入新对象的过程,但是我不太确定EF Core是如何处理它的.每当我尝试复制对象时,都会出现

Some other Stackoverflow threads have mentioned that EF will handle inserting new objects for you even if the same primary key exists in the database, but I'm not quite sure that's how EF Core is handling it. Whenever I try and copy an object I get an error of

Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to OFF

基本上,我只需要一种干净的方法来复制对象,根据用户输入对其进行一些更改,然后将该副本重新插入数据库中,并让ID自动正确递增.是否有最佳实践或简单的方法来执行此操作,而不必手动将属性设置为null或为空?

Basically I just need a clean way to copy an object, make some changes to it based on user input, and then insert that copy back into the database, and have the Id auto-increment properly. Is there a best practice or simple way of doing this without having to manually set properties to null or empty?

用于从数据库中检索对象的示例代码:

Example code for retrieving the object from the database:

    public Incident GetIncidentByIdForCloning(int id)
    {
        try
        {
            return _context.Incident.Single(i => i.IncidentId == id);
        }
        catch
        {
            return null;
        }
    }

检索对象后的代码(由于某些字段是自动生成的,例如作为时间戳的RowVersion):

Code after retrieving object (As some fields are auto-generated like RowVersion which is a Timestamp):

public IActionResult Clone([FromBody]Incident Incident)
    {
        var incidentToCopy = _incidentService.IncidentRepository.GetIncidentByIdForCloning(Incident.IncidentId);
        incidentToCopy.IncidentTrackingRefId = _incidentService.IncidentRepository.GetNextIdForIncidentCategoryAndType(
            Incident.IncidentCategoryLookupTableId, Incident.IncidentTypeLookupTableId).GetValueOrDefault(0);
        incidentToCopy.RowVersion = null;
        incidentToCopy.IncidentId = 0; //This will fail with or without this line, this was more of a test to see if manually setting would default the insert operation, such as creating a brand new object would normally do.
        incidentToCopy.IncidentCategoryLookupTableId = Incident.IncidentCategoryLookupTableId;
        incidentToCopy.IncidentTypeLookupTableId = Incident.IncidentTypeLookupTableId;
        var newIncident = _incidentService.IncidentRepository.CreateIncident(incidentToCopy);
...

我意识到我可以制作一个全新的对象并进行左手复制,但这似乎效率很低,我想知道EF Core是否提供更好的解决方案.

I realize I could just make an entirely new object and do left-hand copying, but that seems terribly inefficient and I want to know if EF Core offers better solutions.

推荐答案

因此,我经历可能重复"线程的次数比我在创建此线程时最初偶然发现它时所经历的要多一些,如此高调的解决方案使我忽略了,当从数据库中检索对象时,它基本上只是立即获取所有值-并且在处理过程中不会检索对该对象的引用.我的代码现在看起来像这样:

So I went through the "Possible duplicate" thread a bit more than I did when I initially stumbled upon it before creating this one, and there was a not-so-highly upvoted solution that I overlooked that essentially just grabs all of the values at once when retrieving the object from the database - and it doesn't retrieve a reference to that object in the process. My code now looks something like this:

try
{
    var incidentToCopy = _context.Incident.Single(i => i.IncidentId == id);
    return (Incident) _context.Entry(incidentToCopy).CurrentValues.ToObject();
}

这篇关于EntityFramework Core-复制实体并将其放回数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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