C# 使用Fluent Api的零或一对一关系EF Core
如果我有模型:C# 使用Fluent Api的零或一对一关系EF Core,c#,entity-framework,orm,ef-code-first,ef-core-2.0,C#,Entity Framework,Orm,Ef Code First,Ef Core 2.0,如果我有模型: public class User { public Account Account { get; set; } public string SomeInfo { get; set; } public Guid Id { get; set; } } public class Account { public Guid Id { get; set; } public string Name { get; set; } } public c
public class User
{
public Account Account { get; set; }
public string SomeInfo { get; set; }
public Guid Id { get; set; }
}
public class Account
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{
public virtual void Configure(EntityTypeBuilder<User> builder)
{
builder.HasKey(x => x.Id);
builder
.Property(t => t.Id)
.ValueGeneratedOnAdd();
}
}
公共类用户
{
公共帐户{get;set;}
公共字符串SomeInfo{get;set;}
公共Guid Id{get;set;}
}
公共类帐户
{
公共Guid Id{get;set;}
公共字符串名称{get;set;}
}
公共类UserEntityTypeConfiguration:IEntityTypeConfiguration
{
公共虚拟空间配置(EntityTypeBuilder)
{
HasKey(x=>x.Id);
建设者
.Property(t=>t.Id)
.ValueGeneratedOnAdd();
}
}
当我运行下面的测试时,它显示该帐户已从用户中删除,但未从数据库中删除
[Test]
public async Task GivenAUser_WhenISetTheAccountToNull_ThenTheAccountIsRemovedFromTheDatabase()
{
Guid userId;
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User newUser = new User
{
SomeInfo = "SomeInfo",
Account = new Account
{
Name = "Name"
}
};
await userRepository.SaveAsync(newUser);
userId = newUser.Id;
}
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User user = await userRepository.GetAsync(userId);
user.Account = null;
await userRepository.SaveAsync(user);
}
User userDb;
int userAccountsCount;
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
userAccountsCount = await dbContext.Set<UserAccount>().CountAsync();
userDb = await userRepository.GetAsync(userId);
}
Assert.That(userDb.Account, Is.EqualTo(null)); // true
Assert.That(userAccountsCount, Is.EqualTo(0)); // false
}
[测试]
公共异步任务在将帐户设置为从数据库()中移除帐户时为用户提供
{
Guid用户标识;
使用(DbContext=GetDbContext())
{
UserRepository UserRepository=新的UserRepository(dbContext);
用户newUser=新用户
{
SomeInfo=“SomeInfo”,
账户=新账户
{
Name=“Name”
}
};
wait userRepository.SaveAsync(newUser);
userId=newUser.Id;
}
使用(DbContext=GetDbContext())
{
UserRepository UserRepository=新的UserRepository(dbContext);
User=await userRepository.GetAsync(userId);
user.Account=null;
等待userRepository.SaveAsync(用户);
}
用户数据库;
int useraccountscont;
使用(DbContext=GetDbContext())
{
UserRepository UserRepository=新的UserRepository(dbContext);
UserAccountScont=await dbContext.Set().CountAsync();
userDb=await userRepository.GetAsync(userId);
}
Assert.That(userDb.Account,Is.EqualTo(null));//true
Assert.That(useraccountscont,Is.EqualTo(0));//false
}
我试图创建一个UserEntityTypeConfiguration,在一个可选字段上设置cascade delete,但在一个可选字段上似乎无法实现
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{
public virtual void Configure(EntityTypeBuilder<User> builder)
{
builder.HasKey(x => x.Id);
builder
.Property(t => t.Id)
.ValueGeneratedOnAdd();
builder.HasOne(x => x.Account)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
}
}
公共类UserEntityTypeConfiguration:EntityTypeConfiguration
{
公共虚拟空间配置(EntityTypeBuilder)
{
HasKey(x=>x.Id);
建设者
.Property(t=>t.Id)
.ValueGeneratedOnAdd();
builder.HasOne(x=>x.Account)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
}
}
有人能帮忙吗?我能问一下,严格说来,你需要一对一的关系吗?因为数据库只会认为这是一对多的关系。数据库实际上不知道一对一是什么。“一对一”在做什么?我可以问一下,严格来说,你需要一对一的关系吗?因为数据库只会将其视为一对多。数据库实际上不知道一对一是什么。一对一在做什么?您没有删除帐户实体。你只是在试探与用户的关系。此外,您在Fluent API中配置的是“如果用户实体被删除,则删除相关的帐户实体”。而不是此选项
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User user = await userRepository.GetAsync(userId);
user.Account = null;
await userRepository.SaveAsync(user);
}
您应该删除实体本身
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User user = await userRepository.GetAsync(userId);
Account acc = user.Account;
dbContext.Entity(acc).State = EntityState.Deleted;
dbContext.SaveChangesAsync();
}
如果您想使用存储库模式,您可以自由地实现自己的解决方案。您没有删除帐户实体。你只是在试探与用户的关系。此外,您在Fluent API中配置的是“如果用户实体被删除,则删除相关的帐户实体”。而不是此选项
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User user = await userRepository.GetAsync(userId);
user.Account = null;
await userRepository.SaveAsync(user);
}
您应该删除实体本身
using (DbContext dbContext = GetDbContext())
{
UserRepository userRepository = new UserRepository(dbContext);
User user = await userRepository.GetAsync(userId);
Account acc = user.Account;
dbContext.Entity(acc).State = EntityState.Deleted;
dbContext.SaveChangesAsync();
}
如果您想使用repository模式,您可以自由地实现自己的解决方案。我有一些我希望映射到数据库的类。你是不是建议我应该有一个用户表,其中包含帐户名,并将其映射到两个类?嗯,id是一对一的。你能不能不把它们放在同一个类下?我想将它们分开。如果我把用户名放在user下面,你会认为是用户名,而不是帐户名。让Account对象具有名称是有意义的。是否可以查看这些类?它们在示例中位于顶部?我有一些我希望映射到数据库的类。你是不是建议我应该有一个用户表,其中包含帐户名,并将其映射到两个类?嗯,id是一对一的。你能不能不把它们放在同一个类下?我想将它们分开。如果我把用户名放在user下面,你会认为是用户名,而不是帐户名。让Account对象具有名称是有意义的。是否可以查看这些类?它们在示例中位于顶部?嗨,Okan,这看起来很棒。如果我加载该用户,然后删除该帐户,然后将该用户传递到要保存的存储库,当我获取该用户以便可以删除该帐户时,它将重新加载该用户并覆盖我所做的任何更改。你知道我如何避免这种情况,直接获取与用户相关的帐户吗?关于直接访问。我建议您配置一对一关系以访问LINQ查询中帐户实体的用户。比如
db.Account.Where(p=>p.User.Id==userId)代码>或者,您可以为两侧设置FK并同时使用它。我不明白你在更新用户时想要达到什么目的。如果您成功删除了帐户实体,它将不会再次加载。嗨,Okan,这看起来棒极了。如果我加载该用户,然后删除该帐户,然后将该用户传递到要保存的存储库,当我获取该用户以便可以删除该帐户时,它将重新加载该用户并覆盖我所做的任何更改。你知道我如何避免这种情况,直接获取与用户相关的帐户吗?关于直接访问。我建议您配置一对一关系以访问LINQ查询中帐户实体的用户。比如db.Account.Where(p=>p.User.Id==userId)代码>或者,您可以为两侧设置FK并同时使用它。我不明白你在说什么