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");
}
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 的例子,使用依赖注入的存储库和工作单元模式。在尝试创建一些独特的东西之前先掌握这些。未来的开发人员在查看您的代码时会感谢您。:)
- 3 回答
- 0 关注
- 213 浏览
添加回答
举报