为了账号安全,请及时绑定邮箱和手机立即绑定

C# 实体框架(代码优先),在模型上实现 CRUD 操作

C# 实体框架(代码优先),在模型上实现 CRUD 操作

C#
凤凰求蛊 2021-08-07 15:34:28
我只是想知道您是否可以在模型(CRUD 事务)中存储一个看起来像这样的函数:我现有的代码:public class tbluser{    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]    public int id { get; set; }    [Required(ErrorMessage = "Username is required")]    public string username { get; set; }    [Required(ErrorMessage = "Password is required")]    public string password { get; set; }    public static List<tbluser> list()    {        using (var db = new sample())        {            var user = db.tbluser.ToList();            return user;        }    }}我想要的是:public class tbluser:DbContext{    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]    public int id { get; set; }    [Required(ErrorMessage = "Username is required")]    public string username { get; set; }    [Required(ErrorMessage = "Password is required")]    public string password { get; set; }    public static List<tbluser> list()    {        return this.toList();    }}我也想问一下实现实体框架的方法是否可以。
查看完整描述

3 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

下面是一个快速示例,说明如何设置简单的 Code First 实现以开始使用。


首先,定义您的用户模型。整数类型的 Key 属性会自动为您配置身份属性。然后,如果您计划按用户名进行频繁查找(以获取用户详细信息或验证密码),则可能需要用户名索引。


public class User

{

    [Key] // Becomes identity by default

    public int Id { get; set; }

    [Index("IX_User_Username", IsUnique = true)]

    public string Username { get; set; }

    public string Password { get; set; }

}

然后,您可以定义


public class AppDataContext : DbContext

{

    public AppDataContext() : base("name=DBConnection") { }

    public DbSet<User> Users { get; set; }

}

您只需要确保您的配置文件中有一个连接字符串来匹配那里传递的名称。


<connectionStrings>

    <add name="DBConnection"  providerName="System.Data.SqlClient"

        connectionString="Data Source=instancePath;Initial Catalog=dbName;Integrated Security=true;MultipleActiveResultSets=True" />

</connectionStrings>

这现在将允许您创建这样的存储库:


public class UserRepo : IDisposable

{

    public Lazy<AppDataContext> _db = new Lazy<AppDataContext>(() => new AppDataContext());


    public IQueryable<User> Get() => _db.Value.Users.AsQueryable();

    public IList<User> GetAll() => _db.Value.Users.ToList();


    public void Dispose()

    {

        if (_db.IsValueCreated)

            _db.Value.Dispose();

    }

}

因此,您可以直接使用 repo 或上下文。


// Use the repo

using (var userRepo = new UserRepo())

{

    var allUsers = userRepo.GetAll();

    var user = userRepo.Get().FirstOrDefault(m => m.Username == "myUsername");

}

// Or just use the data context

using (var db = new AppDataContext())

{

    var allUsers = db.Users.ToList(); // Get all users

    var user = db.Users.FirstOrDefault(m => m.Username == "myUsername");

}


查看完整回答
反对 回复 2021-08-07
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

有一个著名的原则叫做“关注点分离”,如果你这样做会很生气。我的建议是保持代码简单、有意义和松散耦合。


查看完整回答
反对 回复 2021-08-07
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

像这样的代码将会有很大的问题。


在第一个示例中,您将 DbContext 的实例与实体紧密耦合。调用 tblUser.list() 将返回一个用户实体列表,但这些实体现在不在 DbContext 的范围内。(由于using()块关闭)这意味着检索相关实体的任何延迟加载调用都将失败,并且在将它们重新附加到另一个 DbContext 之前,您无法保留对实体的任何更改。这变得非常混乱,非常快。


在第二个示例中,您将扩展 DbContext,这意味着每个“实体”都有效地限定了 DbContext 使用范围以填充其自身的实例。您不能只是“静态”包装方法,因为这对从 DbContext 继承的非静态 DbSet 没有可见性。


这在性能方面会很糟糕,从代码的角度来看,这看起来很奇怪:


IE


using (var user = new tbluser)

{

   var users = user.list(); // not static.

   // .. Do stuff..

}

使它成为静态将是有问题的,因为 DbContext 需要在 tbluser 中是静态范围的


public class tbluser

{

   private static MyContext _context = new MyContext();


   // ...


   public static List<tbluser> list()

   {

      return _context.tblusers.ToList();

   }

}

这可能仍然存在问题,例如静态实例在远程运行之前如何处理,但我当然不能推荐这样的方法。


相反,按预期使用 DbContext。看看像 Unity 或 Autofac 这样的 IoC 容器来管理 DbContext 的生命周期范围,并将实例作为依赖项注入需要它的类,或者至少将它包装在一个using() {}块中,并将其视为具有 DbSet 的存储库。


有很多有效使用 DbContext 的例子,使用依赖注入的存储库和工作单元模式。在尝试创建一些独特的东西之前先掌握这些。未来的开发人员在查看您的代码时会感谢您。:)


查看完整回答
反对 回复 2021-08-07
  • 3 回答
  • 0 关注
  • 213 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信