3

我将 EF 6 与 ODP.Net 一起Oracle.ManagedDataAccess用于我的 ASP.Net MVC Web 应用程序。

我有以下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,我使用EmployeeEmployeeContext这样的:

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

当我使用调试输出控制台进一步调试时,我注意到 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 数据表的列名是全部用大写字母表示(即:."ID"、、".EMPLOYEETYPE"".HOURLYPAY")。

现在,当我将类定义更改为如下内容时:

[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# 编码器,我发现类字段/属性全部大写是很不寻常的。

我的问题是,有没有办法使用大写和小写字母的组合来保留类属性,仅用于查询,生成这些属性的大写字母版本?

同样,如果这些事情很重要,我会使用 EF6.0.0.0和 ODP.NetOracle.ManagedDataAccess版本4.121.2.0Oracle.ManagedDataAccess.EntityFramework版本。6.121.2.0

4

2 回答 2

4

您可以使用Column每个属性的 data 属性来指定创建表时要使用的映射列名称,这与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

您还可以使用 fluent APIDbContext来指定列名映射:

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

于 2016-02-16T04:26:25.620 回答
3

一种更自动化(更简单)的方法是利用 EF自定义代码优先约定功能。

首先你需要一个像这样的简单类

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

你就完成了。

于 2016-02-17T12:48:27.307 回答