Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取本地实体或附加新实体_C#_Entity Framework Core - Fatal编程技术网

C# 获取本地实体或附加新实体

C# 获取本地实体或附加新实体,c#,entity-framework-core,C#,Entity Framework Core,我的实体如下所示: public class User { public int Id {get; set;} } var user1 = ctx.FindTracked(1) ?? ctx.Attach(new User { Id = 1 }).Entity; var user2 = ctx.FindTracked(2) ?? ctx.Attach(new User { Id = 2 }).Entity; AddUserRelation(user1, user2); 我不想每次获得

我的实体如下所示:

public class User
{
    public int Id {get; set;}
}
var user1 = ctx.FindTracked(1) ?? ctx.Attach(new User { Id = 1 }).Entity;
var user2 = ctx.FindTracked(2) ?? ctx.Attach(new User { Id = 2 }).Entity;
AddUserRelation(user1, user2);
我不想每次获得一个特定用户时都查询数据库,因为我知道该Id的用户存在。在这种情况下,Attach似乎有效,但如果DbContext已在本地存储该特定用户的实体,它将抛出异常

我想做的示例:

var user1 = ctx.GetLocalOrAttach(new User{Id = 1});
var user2 = ctx.GetLocalOrAttach(new User{Id = 2});
AddUserRelation(user1, user2);

有什么解决办法吗?如果不是,什么是检查实体是否在本地存在的理想方法。

我已经使用EF多年了,而且我从未使用过附加机制,它通常只会让你陷入麻烦。
如果我看一下代码,我猜您希望在两个用户记录之间创建一个关系,但是您希望通过不查询两个用户记录来优化性能。(就我个人而言,我不在乎获取用户对象所需的20毫秒开销,但我想这可能很重要)。

EF允许您使用外键创建记录,而无需加载外部实体。
因此,您可以从更改以下代码:

var user1 = context.Users.Find(1);
var user2 = context.Users.Find(2);
var userRelation = new UserRelation();
userRelation.FromUser = user1;
userRelation.ToUser = user2;
context.UserRelations.Add(userRelation);
致:

请注意,在我的上一个代码示例中,我没有查询两个用户对象,但EF将使用两个有效外键创建UserRelation记录。

您可以搜索该属性,但这将是低效的

IMO的一个更好的方法是使用
FindTracked
自定义扩展方法


我将大多数数据库逻辑包装到存储库中。当我处理两个或多个不同的实体时,创建一个像AddRelation(int fromId,int toId)这样的函数会很糟糕。调用者端的参数交换会导致一个很难找到的错误。此外,我忘了指出,我想要一个有效的方法来更新关系中的单个属性,它与Attach一起工作得很好。
using Microsoft.EntityFrameworkCore.Internal;

namespace Microsoft.EntityFrameworkCore
{
    public static partial class CustomExtensions
    {
        public static TEntity FindTracked<TEntity>(this DbContext context, params object[] keyValues)
            where TEntity : class
        {
            var entityType = context.Model.FindEntityType(typeof(TEntity));
            var key = entityType.FindPrimaryKey();
            var stateManager = context.GetDependencies().StateManager;
            var entry = stateManager.TryGetEntry(key, keyValues);
            return entry?.Entity as TEntity;
        }
    }
}
var user1 = ctx.FindTracked(1) ?? ctx.Attach(new User { Id = 1 }).Entity;
var user2 = ctx.FindTracked(2) ?? ctx.Attach(new User { Id = 2 }).Entity;
AddUserRelation(user1, user2);