带有 ODP.Net Oracle.ManagedDataAccess 的 EF 6,如何对 Class 属性使用非大写字母?
EF 6 with ODP.Net Oracle.ManagedDataAccess, How to Use Non-Capital Letter for Class Properties?
我将 EF 6 与 ODP.Net Oracle.ManagedDataAccess
一起用于我的 ASP.Net MVC Web 应用程序。
我有以下名为 Employee
的 Model
(在 Model\Employee.cs
文件中):
[Table("TBLEMPLOYEE")]
public class Employee {
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public DateTime DateOfBirth { get; set; }
public int EmployeeType { get; set; }
public double? AnnualSalary { get; set; }
public double? HourlyPay { get; set; }
public double? HoursWorked { get; set; }
public string City { get; set; }
}
以及EmployeeContext.cs
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("myschema");
}
}
然后,在我的 EmployeeController.cs
中,我像这样使用 Employee
和 EmployeeContext
:
public ActionResult Details(int id = 1) {
try {
EmployeeContext employeeContext = new EmployeeContext();
employeeContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Employee employee = employeeContext.Employees.Single(x => x.ID == id);
return View(employee);
} catch (Exception e) {
return View(e);
}
}
当我收到以下内部异常错误时:
Oracle.ManagedDataAccess.Client.OracleException: ORA-00904: "Extent1"."Id": invalid identifier
异常错误发生在:
Employee employee = employeeContext.Employees.Single(x => x.ID == id);
当我使用调试输出控制台进一步调试时,我注意到 EF 生成以下 SQL 查询来获取数据:
SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "MYSCHEMA"."TBLEMPLOYEE" "Extent1"
WHERE ("Extent1"."Id" = :p__linq__0) AND (ROWNUM <= (2) )
随着我进行更多研究,我了解到由于 SQL 查询列名称中存在引号 " "
(例如 ."Id"
、".EmployeeType"
、".HourlyPay"
等),查询找不到匹配的列名,因为Oracle数据Table列名全部用大写字母表示(即:."ID"
、".EMPLOYEETYPE"
、".HOURLYPAY"
等等)。
现在,当我将 class 定义更改为如下内容时:
[Table("TBLEMPLOYEE")]
public class Employee {
public int ID { get; set; }
public string NAME { get; set; }
public string GENDER { get; set; }
public DateTime DATEOFBIRTH { get; set; }
public int EMPLOYEETYPE { get; set; }
public double? ANNUALSALARY { get; set; }
public double? HOURLYPAY { get; set; }
public double? HOURSWORKED { get; set; }
public string CITY { get; set; }
}
它工作得很好。 但我不想要那个。
作为一名典型的 C# 编码员,我发现 非常不寻常 class fields/properties.
的所有字母都大写
我的问题是,是否有任何方法可以保留使用大写字母和小写字母组合的 class 属性,仅用于查询,生成这些属性的大写字母版本?
同样,如果这些事情很重要,我会使用 EF 6.0.0.0
和 ODP.Net Oracle.ManagedDataAccess
版本 4.121.2.0
和 Oracle.ManagedDataAccess.EntityFramework
版本 6.121.2.0
。
您可以在每个 属性 上使用 Column
数据属性来指定在创建 table 时要使用的映射列名称,与 Table
属性。然后,您的实际 属性 名称可以正确格式化:
[Table("TBLEMPLOYEE")]
public class Employee {
[Column("ID")]
public int Id { get; set; }
[Column("NAME")]
public string Name { get; set; }
etc...
}
更多信息:https://msdn.microsoft.com/en-us/data/jj591583.aspx#TableColumn
您还可以在 DbContext
中使用流畅的 API 来指定列名映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure Column
modelBuilder.Entity<Employee>()
.Property(p => p.Id)
.HasColumnName("ID");
modelBuilder.Entity<Employee>()
.Property(p => p.Name)
.HasColumnName("NAME");
}
参考:http://www.entityframeworktutorial.net/code-first/configure-property-mappings-using-fluent-api.aspx
一种更自动化(更简单)的方法是利用 EF Custom Code First Conventions 功能。
首先你需要一个像这样的简单class
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Core.Metadata.Edm;
public class UppercaseColumnNameConvention : IStoreModelConvention<EdmProperty>
{
public void Apply(EdmProperty item, DbModel model)
{
item.Name = item.Name.ToUpper();
}
}
然后在您的上下文中 class
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add<UppercaseColumnNameConvention>();
// ...
}
大功告成。
我将 EF 6 与 ODP.Net Oracle.ManagedDataAccess
一起用于我的 ASP.Net MVC Web 应用程序。
我有以下名为 Employee
的 Model
(在 Model\Employee.cs
文件中):
[Table("TBLEMPLOYEE")]
public class Employee {
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public DateTime DateOfBirth { get; set; }
public int EmployeeType { get; set; }
public double? AnnualSalary { get; set; }
public double? HourlyPay { get; set; }
public double? HoursWorked { get; set; }
public string City { get; set; }
}
以及EmployeeContext.cs
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("myschema");
}
}
然后,在我的 EmployeeController.cs
中,我像这样使用 Employee
和 EmployeeContext
:
public ActionResult Details(int id = 1) {
try {
EmployeeContext employeeContext = new EmployeeContext();
employeeContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Employee employee = employeeContext.Employees.Single(x => x.ID == id);
return View(employee);
} catch (Exception e) {
return View(e);
}
}
当我收到以下内部异常错误时:
Oracle.ManagedDataAccess.Client.OracleException: ORA-00904: "Extent1"."Id": invalid identifier
异常错误发生在:
Employee employee = employeeContext.Employees.Single(x => x.ID == id);
当我使用调试输出控制台进一步调试时,我注意到 EF 生成以下 SQL 查询来获取数据:
SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "MYSCHEMA"."TBLEMPLOYEE" "Extent1"
WHERE ("Extent1"."Id" = :p__linq__0) AND (ROWNUM <= (2) )
随着我进行更多研究,我了解到由于 SQL 查询列名称中存在引号 " "
(例如 ."Id"
、".EmployeeType"
、".HourlyPay"
等),查询找不到匹配的列名,因为Oracle数据Table列名全部用大写字母表示(即:."ID"
、".EMPLOYEETYPE"
、".HOURLYPAY"
等等)。
现在,当我将 class 定义更改为如下内容时:
[Table("TBLEMPLOYEE")]
public class Employee {
public int ID { get; set; }
public string NAME { get; set; }
public string GENDER { get; set; }
public DateTime DATEOFBIRTH { get; set; }
public int EMPLOYEETYPE { get; set; }
public double? ANNUALSALARY { get; set; }
public double? HOURLYPAY { get; set; }
public double? HOURSWORKED { get; set; }
public string CITY { get; set; }
}
它工作得很好。 但我不想要那个。
作为一名典型的 C# 编码员,我发现 非常不寻常 class fields/properties.
的所有字母都大写我的问题是,是否有任何方法可以保留使用大写字母和小写字母组合的 class 属性,仅用于查询,生成这些属性的大写字母版本?
同样,如果这些事情很重要,我会使用 EF 6.0.0.0
和 ODP.Net Oracle.ManagedDataAccess
版本 4.121.2.0
和 Oracle.ManagedDataAccess.EntityFramework
版本 6.121.2.0
。
您可以在每个 属性 上使用 Column
数据属性来指定在创建 table 时要使用的映射列名称,与 Table
属性。然后,您的实际 属性 名称可以正确格式化:
[Table("TBLEMPLOYEE")]
public class Employee {
[Column("ID")]
public int Id { get; set; }
[Column("NAME")]
public string Name { get; set; }
etc...
}
更多信息:https://msdn.microsoft.com/en-us/data/jj591583.aspx#TableColumn
您还可以在 DbContext
中使用流畅的 API 来指定列名映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure Column
modelBuilder.Entity<Employee>()
.Property(p => p.Id)
.HasColumnName("ID");
modelBuilder.Entity<Employee>()
.Property(p => p.Name)
.HasColumnName("NAME");
}
参考:http://www.entityframeworktutorial.net/code-first/configure-property-mappings-using-fluent-api.aspx
一种更自动化(更简单)的方法是利用 EF Custom Code First Conventions 功能。
首先你需要一个像这样的简单class
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Core.Metadata.Edm;
public class UppercaseColumnNameConvention : IStoreModelConvention<EdmProperty>
{
public void Apply(EdmProperty item, DbModel model)
{
item.Name = item.Name.ToUpper();
}
}
然后在您的上下文中 class
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add<UppercaseColumnNameConvention>();
// ...
}
大功告成。