我在我的ASP.Net MVC Web应用程序中使用带有ODP.Net Oracle.ManagedDataAccess
的EF 6。
我有以下Model
名为Employee
(在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”:标识符无效
异常错误发生在:
Employee employee = employeeContext.Employees.Single(x => x.ID == id);
当我使用我的Debug输出控制台进一步调试时,我注意到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"
,{{ 1}}等等,查询找不到匹配的列名,因为Oracle数据表列名全部用大写字母表示(即".HourlyPay"
,."ID"
,".EMPLOYEETYPE"
和等等。)
现在,当我将类定义更改为类似的内容时:
".HOURLYPAY"
它完美无缺。 但我不想那样。
作为一个典型的C#编码器,我发现非常不寻常为类字段/属性设置所有大写字母。
我的问题是,有没有办法保留使用大写和小写字母组合的类属性,但仅用于查询,生成这些属性的大写字母版本?
同样,如果这些事情很重要,我会使用EF [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; }
}
和ODP.Net 6.0.0.0
版本Oracle.ManagedDataAccess
以及4.121.2.0
版本Oracle.ManagedDataAccess.EntityFramework
。
答案 0 :(得分:3)
您可以在每个属性上使用Column
数据属性来指定在创建表时使用的映射列名称,与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
中使用fluent 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
答案 1 :(得分:2)
更自动化(更简单)的方法是使用EF Custom Code First Conventions功能。
首先,您需要一个像这样的简单类
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();
}
}
然后在你的上下文类
中protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add<UppercaseColumnNameConvention>();
// ...
}
你已经完成了。