簡體   English   中英

C#實體框架(代碼優先),在模型上實現CRUD操作

[英]C# Entity Framework (Code first), Implementing CRUD Operations on Model

我只是想知道您是否可以將函數存儲在模型中(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();
    }
}

我只想問一下實現實體框架的方法是否還可以。

這樣的代碼將存在嚴重問題。

在第一個示例中,您將DbContext的實例緊密耦合到實體。 調用tblUser.list()將返回用戶實體的列表,但是現在這些實體不在DbContext的范圍之內。 (由於using()塊的關閉),這意味着檢索相關實體的所有惰性加載調用都將失敗,並且在將它們重新附加到另一個DbContext之前,您無法保留對實體的任何更改。 這變得非常混亂,非常快。

在第二個示例中,您將擴展DbContext,這意味着每個“實體”都有效地確定了DbContext用於填充其自身實例的范圍。 您不能只是“靜態”包裝該方法,因為這樣就無法看到從DbContext繼承的非靜態DbSet。

就性能而言,這將是可怕的,並且從代碼角度來看,這看起來很奇怪:

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的示例,將存儲庫和工作單元模式與依賴項注入一起使用。 嘗試創建一些獨特的東西之前,請先掌握它們。 未來的開發人員正在查看您的代碼,將感謝您。 :)

有一項著名的原則稱為“ 關注點分離 ”,如果您這樣做,將會非常生氣。 我的建議是使代碼保持簡單,有意義和松散耦合。

這是一個簡單的示例,說明如何設置簡單的Code First實現以開始使用。

首先,定義您的用戶模型。 整數類型的Key屬性會自動為您配置identity屬性。 然后,如果您打算按用戶名進行頻繁查找(以獲取用戶詳細信息或驗證密碼),則可能需要在用戶名上建立索引。

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

因此,您可以直接使用存儲庫或上下文。

// 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");
}

有關更多信息,以下是一些有用的鏈接,其中包含詳細信息:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM