解決EF使用context.Database.SqlQuery時NotMapped屬性列為空null的問題(轉載)
阿新 • • 發佈:2018-12-26
有時候我們要為EF中的Model加一個新屬性,這個屬性不是資料庫中的欄位,而是從其它表中關聯出來的。EF中要標示一個列不是對應表中欄位只需要加上NotMapped特性。要使用NotMapped,保證你的專案引用了System.ComponentModel.DataAnnotations.dll,NotMapped特性在名稱空間System.ComponentModel.DataAnnotations.Schema下。比如我們有一個Employee實體:
public class Employee { public int EmployeeId { get; set; }public string EmployeeName { get; set; } [NotMapped] public string CustomerName { get; set; } }
可能你會想到用context.Database.SqlQuery寫一句原生的sql為CustomerName賦值,就像下面的程式碼:
public List<Employee> GetEmployees() { using (MyContext context = new MyContext()) { return context.Database.SqlQuery<Employee>("select E.EmployeeId, E.EmployeeName, C.CustomerName from Employee E left join Customer C on E.CustomerId = C.CustomerId").ToList(); } }
但是遺憾是上面程式碼欄位CustomerName始終都為空。因為使用context.Database.SqlQuery雖然是傳的sql語句,但是它和原生的ADO.NET還是不一樣,它還是會走一下EF框架,用NotMapped標示的欄位,EF會忽略掉這個欄位,當生成sql語句也不會包含這個欄位,無論你增,改,查都不會管這個字欄位,所以讀出來始終為空null值。下面介紹一種利用linq的變通的辦法。
public class EmployeeVM { public int EmployeeId { get; set; } public string EmployeeName { get; set; } public string CustomerName { get; set; } }
呼叫EF並使用linq的left join讀取屬性:
public List<Employee> GetEmployees() { using (MyContext context = new MyContext()) { return context.Database.SqlQuery<EmployeeVM>("select E.EmployeeId, E.EmployeeName, C.CustomerName from Employee E left join Customer C on E.CustomerId = C.CustomerId") .Select(x=> new Employee(){ EmployeeId = x.EmployeeId, EmployeeName = x.EmployeeName, CustomerName = x.CustomerName }).ToList(); } }