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);