配置使用EF6.0常見的一些問題及解決方案

前言

最近做了個winform小項目,爲方便快速開發,後臺框架使用了ef6.0+sqlserver2008架構,遇到各種問題,真是傷腦筋。現將遇到問題和解決方案寫下來,方便查閱

提示未註冊,找不到驅動程序

No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'. Make sure the provider is registered in the 'entityFramework' section of the application config file.

 

這個問題比較坑,我根據上面的提示,跑到配置文件去查看,看有沒有entutyFramework節點,是否註冊驅動。結果按照網上的解決方案把配置文件貼上去了還是報錯,然後再查看EntityFramework.SqlServer.dll是否已經引用到數據訪問層類庫中,也在。這下就懵逼了,到底是什麼情況,網上各種搜,比如把EntityFramework.SqlServer.dll的賦值到本地屬性設爲True後還是沒有用,折騰了個把小時,最後突然看了一眼bin\Debug目錄,發現只有一個EntityFramework.dll文件,沒有EntityFramework.SqlServer.dll,我就瞬間釋然了,原來是這樣。。。

解決方案:

1.檢查是否引入EntityFramework.dll 和EntityFramework.SqlServer.dll

2.檢查是否設爲複製到本地屬性爲True

3.檢查配置文件是否註冊驅動

如我的是sqlserver數據庫:

<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>

如果是mysql

 <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.8.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
    </providers>

將上面這段代碼放到<entityFramework>節點下面就可以了,並且要引入幾個dll

4.查看編譯後的目錄中是否有這2個dll,如果沒有,手動拷貝進去

提示表名無效

 有時候新加了一個實體類,數據庫也相應加了一個表。然後理所當然的運行增加數據,結果就出現這提示

 排查過程

 然後又是一陣排查,再次確認了數據庫中確實存在表,還手動存進去了一條數據。再跑到BaseContext:DbContext這個類裏面一陣翻,確定已經有  public DbSet<Employee>a_Emp { get; set; }這個屬性了。又跑到實體類中確認字段是否吻合,主鍵[key]標記是否已經標了。最後又對比了之前的項目2個實體之間的差別。最後終於發現。。。實體類沒有和數據庫關聯

 

解決方案

1.確認數據庫表是否存在

2.確認BaseContext:DbContext類中是否有屬性

3.確認實體類中字段與主鍵

4.確認實體與數據庫表是否關聯

 

    [Table("a_Emp")]
    public class Employee

另:實體類上面的[table]小括號裏面的就是數據庫的表名,並且該標記需要引用dll

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

 數據庫字段記錄爲null時 ef 操作數據庫報錯

   

錯誤排查

這個問題是數據庫字段爲空導致的,ef 反射賦值時實體時發生的錯誤,如:ToList()、

_db.Set<TEntity>().AddRange(entry);
_db.SaveChanges();

解決方案

2種任選一種

1.將數據庫所有字段都賦值,不存在爲空的情況 自然不會報錯,但畢竟繁瑣

2.將數據庫中可空字段再實體中用可空類型表示

如:

public DataTime? CreateTime{get;set;}
public int? Num{get;set;}
public decimal? Pirce{get;set;}

目前我知道的就這2種,應該夠用了

EF中的外鍵

 外鍵是常用的數據關聯形式,在數據訪問中佔據重要位置,下面來看看使用外鍵的幾個步驟

一、將2個實體類都準備好,一個主鍵表一個外鍵表,例如 員工表中需要部門編號 那麼就需要準備員工類和部門類

二、在員工實體類Employee中加入一個對象實體,加一個部門Id,沒錯,不是一個單純的部門ID 而是實體

    [Key]
        public int EmpId { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string EmpName { get; set; }
        /// <summary>
        /// 性別
        /// </summary>
        public string Sex { get; set; }
        /// <summary>
        /// 生日
        /// </summary>
        public DateTime BirthDay { get; set; }
           
        /// <summary>
        /// 部門
        /// </summary>
        public int DepId { get; set; }

        /// <summary>
        /// 關聯主表
        /// </summary>
        [ForeignKey("DepId")] 

public Dept Dept { get; set; } //注意:ForeignKey("DepId")中的DepId 就是員工類的外鍵

四、Dept部門表中必須有主鍵

五、調用的時候

 db.a_Emp.Include("Dept").Where(l => l.Dept.name.Contains(name)||string.IsNullOrEmpty(name)).ToList()

其中a_Emp是員工類的實體對象,在baseContext裏面的 public DbSet<Employee>a_Emp { get; set; }

Dept.name是可以直接點出來的了

 HttpContext.User.Identity.IsAuthenticated一直爲false

使用mvc時會用到權限控制,並且存cookie,然後一般會出現下面的一段代碼

 protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var response = filterContext.HttpContext.Response;
             
            currentUser = new AdminUser();
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                long.TryParse(System.Web.HttpContext.Current.User.Identity.Name, out userid);
                if (userid > 0)
                {
                    currentUser = AdminUserDAL.getEntryById<AdminUser, long>(userid);
                    currentUser.allprivileges = AdminUserDAL.getUserPrivilegeAll(-1, userid);
                    myPermissionList = currentUser.allprivileges;
                }
            }
            else //返回登錄頁
            {
                response.Redirect("/Acount/Login");
            }

一直爲false的時候就會出現始終跳到登錄頁,就算調試也找不到爲什麼會這樣

解決方案

   在webconfig文件的system.web節點下面加入節點就行了

  <authentication mode="Forms">
      <forms loginUrl="~/Home/Login" name="paochi.com" timeout="300" protection="All" path="/" requireSSL="false" slidingExpiration="false" enableCrossAppRedirects="false" cookieless="UseCookies" />
    </authentication>

裏面的內容可以自己根據需要配置

總結

以上是我遇到的衆多問題之一,限於篇幅和時間,暫時就記錄到這裏吧。如果有什麼理解錯誤的地方,還望指正!!!

請關注我的博客地址:http://www.cnblogs.com/jingch 給個贊吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章