EF 6 with ODP.Net Oracle.ManagedDataAccess, How to Use Non-Capital Letter for Class Properties?

為{幸葍}努か 提交于 2019-12-20 02:58:22

问题


I am using the EF 6 with ODP.Net Oracle.ManagedDataAccess for my ASP.Net MVC Web application.

I have the following Model called Employee (in Model\Employee.cs file):

[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; }
}

As well as EmployeeContext.cs

public class EmployeeContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.HasDefaultSchema("myschema");
    }
}

Then, in my EmployeeController.cs, I use the Employee and the EmployeeContext like this:

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

When I get the following Inner exception error:

Oracle.ManagedDataAccess.Client.OracleException: ORA-00904: "Extent1"."Id": invalid identifier

The exception error occurs in:

Employee employee = employeeContext.Employees.Single(x => x.ID == id);

As I debug further by using my Debug output console, I noticed that the EF generates the following SQL query to fetch the data:

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

And as I do some more research, I understand that due to the present of the quotation marks " " in the SQL query column names (such as ."Id", ".EmployeeType", ".HourlyPay" and so on), the query cannot find matching Column names as the Oracle Data Table column name is all represented in capital letters (that is: ."ID", ".EMPLOYEETYPE", ".HOURLYPAY" and so on).

Now, when I changed the class definition into something like this:

[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; }
}

It works perfectly fine. But I do not want that.

As a typical C# coder, I found it quite unusual to have all capital letters for class fields/properties.

My question is, is there any way to retain the class properties using combination of capital and small letters yet, only for querying, generated capitalized letters version of those properties?

Again, I use EF 6.0.0.0 and ODP.Net Oracle.ManagedDataAccess version 4.121.2.0 and Oracle.ManagedDataAccess.EntityFramework version 6.121.2.0 if those things matter.


回答1:


You can use the Column data attribute on each property to specify the mapped column name to use when the table is created, much the same as the Table attribute. Then, your actual property names can be correctly formatted:

[Table("TBLEMPLOYEE")]
public class Employee {
    [Column("ID")]
    public int Id { get; set; }

    [Column("NAME")]
    public string Name { get; set; }

    etc...
}

More info: https://msdn.microsoft.com/en-us/data/jj591583.aspx#TableColumn

You can also use the fluent API in your DbContext to specify a column name mapping:

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

Reference: http://www.entityframeworktutorial.net/code-first/configure-property-mappings-using-fluent-api.aspx




回答2:


A more automated (easier) way would be to utilize EF Custom Code First Conventions feature.

First you'll need a simple class like this

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

then in your context class

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add<UppercaseColumnNameConvention>();
    // ...
}

and you are done.



来源:https://stackoverflow.com/questions/35423692/ef-6-with-odp-net-oracle-manageddataaccess-how-to-use-non-capital-letter-for-cl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!