2017-04-18 54 views
0

我需要通过代码优先实体框架执行函数时小写列名。我试图使用this link的解决方案,但它只适用于表映射,而不适用于函数映射。由实体框架生成的查询降低壳体

这是我的POCO,它包含函数执行的数据。

public class RBReportInfo 
{ 
    [Key] 
    public int ReportId { get; set; } 
    public int ReportDataViewId { get; set; } 
} 

这是由EF生成的代码,其中fnrbreportinfo是函数名和@reportId是函数参数。

SELECT 
[Extent1].[ReportId] AS [ReportId], 
[Extent1].[ReportDataViewId] AS [ReportDataViewId] 
FROM [dbo].[fnrbreportinfo](@reportId) AS [Extent1] 

下面的代码执行以填充POCO。

var idParameter = new ObjectParameter("reportId", reportId); 
return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<RBReportInfo>(
      $"[{nameof(ReportBuilderContext)}].[fnrbreportinfo](@reportId)", idParameter); 

该代码在OnModelCreating()方法改变的属性的情况下,以在查询匹配小写数据库列名实现。

 modelBuilder.Properties().Configure(c => 
     { 
      var name = c.ClrPropertyInfo.Name.ToLower(); 
      c.HasColumnName(name); 
     }); 

所以,我希望由EF生成的查询如下,其中列名称为小写。

SELECT 
[Extent1].[reportid] AS [ReportId], 
[Extent1].[reportdataviewid] AS [ReportDataViewId] 
FROM [dbo].[fnrbreportinfo](@reportId) AS [Extent1] 

我试图改变属性的名称为小写其作品,但它打破了在C#中,属性命名的PascalCase约定。

public class RBReportInfo 
{ 
    [Key] 
    public int reportid { get; set; } 
    public int reportdataviewid { get; set; } 
} 

我也试过使用属性,但也失败了。

[Column("reportid")] 
public int ReportId{get;set;} 

要求是因为区分大小写的数据库,因为所有的表/函数都是小写的。

+1

“要求是因为区分大小写的数据库,因为所有的表/函数都是小写的。”建议您不使用SQL Server。请说明您正在使用的数据库引擎和实体框架提供程序。这听起来像EF提供商(这是非微软)有一个错误 – Aron

回答

0

我从来没有试过,但它看起来很有希望为你的情况,我恰好在外面看着枫叶。 EF允许拦截,所以你可以拦截查询,或者叫ToLower()command.CommandText

class EFCommandInterceptor: IDbCommandInterceptor 
{ 
    public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
    { 
     LogInfo("NonQueryExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
    { 
     LogInfo("NonQueryExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContextt<System.Data.Common.DbDataReader> interceptionContext) 
    { 
     LogInfo("ReaderExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext) 
    { 
     LogInfo("ReaderExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
    { 
     LogInfo("ScalarExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
    { 
     LogInfo("ScalarExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
    } 

    private void LogInfo(string command, string commandText) 
    { 
     Console.WriteLine("Intercepted on: {0} :- {1} ", command, commandText); 
    } 
} 

你可以阅读更多here

0

为什么不设置属性名称而不是情人命名属性?

[Table("mytable")] 
public class MyTable { 

    [Column("firstcolumn")] 
    public int firstColumn {get;set} 

    [Column("secondcolumn")] 
    public string secondColumn {get;set;} 

} 

这不是一个解决方案,但你可以添加像自定义方法这

public IQueriable<TResult> SelectFromDB<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) 
{ 
     return source.SqlQuery(source.Select(selector).ToString().ToLower()); 
} 

然后

using(var context = new DBContext()) 
{ 
    context.SomeTable.SelectFromDB(data => data).ToList(); 
} 
+0

我忘了提及,也没有工作。 –