无法使用EFCore将类的内部属性保存到DB中



我已经解决了以下-stackoverflow问题,它对我不起作用,我也没有使用导航属性。

Entity,位于-Component.Shared.csproj(所有内容都是公共的(

public class Entity
{
[Key]
public Guid Id { get; set; }
public Guid CreatedBy { get; set; }
public Guid UpdatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime UpdatedOn { get; set; }
}

User位于-Component.User.csproj中,继承了Entity

internal class User : Entity
{
internal string FirstName { get; set; }
internal string MiddleName { get; set; }
internal string LastName { get; set; }
internal string EmailId { get; set; }
internal DateTime DateOfBirth { get; set; }
}

UserDbContext位于组件.用户.csproj.中

internal sealed class UserDbContext : DbContext
{
public UserDbContext(DbContextOptions<UserDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
//Remove pluralizing table name convention (Install package - Microsoft.EntityFrameworkCore.Relational)
foreach (var entity in builder.Model.GetEntityTypes())
{
entity.SetTableName(entity.DisplayName());
}
base.OnModelCreating(builder);
}
internal DbSet<User> Users { get; set; }
}

UserRepository.cs(Component.User.csproj(。

internal class UserRepository : IUserRepository
{
#region Private Fields
// To detect redundant calls
private bool _disposed = false;
private readonly IUnitOfWorkWithDbContext<UserDbContext, User> _uow;        
#endregion Private Fields
public UserRepository(IUnitOfWorkWithDbContext<UserDbContext, User> uow)
{
_uow = uow;
}
bool IRepository<User>.Create(User user)
{
var userEntry = _uow.DbContext.Users.Add(user);
return userEntry.IsAdded(); // IsAdded is an extension method - return EntityState.Added == entityEntry.State;
}
}

问题-我如何强制EF(目前,但将来可能是Dapper/Raw ADO.NET等(保存User或任何类的内部属性值,而不公开它们,以避免来自Components.User.csproj之外的代码的任何直接更改?

您可以通过以下方式设置保存实体的内部属性:

public class ApplicationDbContext : DbContext
{
private readonly IHttpContextAccessor _contextAccessor;
public AuditTrail(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public void SaveChanges()
{
SetAuditInfo();
base.SaveChanges();
}
public Task SaveChangesAsync()
{
SetAuditInfo();
return base.SaveChangesAsync();
}
private void SetAuditInfo()
{
var entries = context.ChangeTracker
.Entries<Entity>()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified)
.ToList();
var claim = _contextAccessor?.HttpContext?.User.Claims.FirstOrDefault(c => c.Type == "UserId")?.Value;
var userId = claim != null ? Guid.Parse(claim) : Guid.Empty;
foreach (var entry in entries)
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedOn = DateTime.Now;
entry.Entity.CreatedBy = userId;
break;
case EntityState.Modified:
entry.Entity.UpdatedOn = DateTime.Now;
entry.Entity.CreatedBy = userId;
break;
}
}
}
}

为了防止更改,您可以创建另一个像UserDto这样的内部属性只有getter的对象,或者从DTO对象中删除它们。

另一个选项是在数据库上设置日期:

entity.Property(e => e.CreatedOn)
.HasDefaultValueSql("(getdate())")
.Metadata.AfterSaveBehavior = PropertySaveBehavior.Throw;

您也可以使用阴影属性:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.Property<DateTime>("CreatedOn");
}

设定值:

context.Entry(user).Property("CreatedOn").CurrentValue = DateTime.Now;

最新更新