Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在查询中生成错误的列_C#_Sql_.net_Nhibernate_Mapping By Code - Fatal编程技术网

C# 在查询中生成错误的列

C# 在查询中生成错误的列,c#,sql,.net,nhibernate,mapping-by-code,C#,Sql,.net,Nhibernate,Mapping By Code,NHibernate存在间歇性问题,它偶尔会在SQL上生成一个列错误的查询。如果我们重新启动应用程序,问题就不再发生(有时需要多次重新启动)。当问题发生时,在该进程的生命周期内,它总是为受影响的实体生成错误的SQL。它不总是同一个受影响的实体 它是一个ASP.NET应用程序,在应用程序启动事件期间创建SessionFactory。所有的配置和映射都是通过代码完成的 我们没有更多的想法如何测试或调试应用程序,我开始假设NHibernate中存在一些bug,因为应用程序在重新启动时会自行修复。任何想

NHibernate存在间歇性问题,它偶尔会在SQL上生成一个列错误的查询。如果我们重新启动应用程序,问题就不再发生(有时需要多次重新启动)。当问题发生时,在该进程的生命周期内,它总是为受影响的实体生成错误的SQL。它不总是同一个受影响的实体

它是一个ASP.NET应用程序,在应用程序启动事件期间创建SessionFactory。所有的配置和映射都是通过代码完成的

我们没有更多的想法如何测试或调试应用程序,我开始假设NHibernate中存在一些bug,因为应用程序在重新启动时会自行修复。任何想法/提示都将不胜感激

下面是一个例子:

实体

namespace Example.Clinicas
{
    public partial class Clinica : Entidade   // Abstract base class that has a property Handle
    {
        public virtual string Ddd { get; set; }
        public virtual string Ddd2 { get; set; }
        public virtual long? Duracao { get; set; }
        public virtual string Numero { get; set; }
        public virtual string Numero2 { get; set; }
        public virtual string Prefixo { get; set; }
        public virtual string Prefixo2 { get; set; }
        public virtual long? HandlePrestador { get; set; }
        public virtual Example.Prestadores.Prestador Prestador { get; set; }
    }
}
映射

namespace Example.Clinicas.Mappings
{
    public class ClinicaMapping : ClassMapping<Clinica>
    {
        public ClinicaMapping() 
        {
            Table("CLI_CLINICA");

            Id(x => x.Handle, map => 
            {
                map.Column("HANDLE");
                map.Generator(Generators.Sequence, g => g.Params(new { sequence = "SEQ_AUTO1816" }));
            });
            Property(x => x.Ddd, map => map.Column( c=> 
            {
                c.Name("DDD1");
                c.Length(4);
            }));
            Property(x => x.Ddd2, map => map.Column( c=> 
            {
                c.Name("DDD2");
                c.Length(4);
            }));
            Property(x => x.Duracao, map => map.Column("INTERVALOAGENDA"));
            Property(x => x.Numero, map => map.Column( c=> 
            {
                c.Name("NUMERO1");
                c.Length(5);
            }));
            Property(x => x.Numero2, map => map.Column( c=> 
            {
                c.Name("NUMERO2");
                c.Length(5);
            }));
            Property(x => x.Prefixo, map => map.Column( c=> 
            {
                c.Name("PREFIXO1");
                c.Length(5);
            }));
            Property(x => x.Prefixo2, map => map.Column( c=> 
            {
                c.Name("PREFIXO2");
                c.Length(5);
            }));
            Property(x => x.HandlePrestador, map => map.Column("PRESTADOR"));
            ManyToOne(x => x.Prestador, map => 
            { 
                map.Column("PRESTADOR");
                map.Insert(false);
                map.Update(false);
            });
        }
    }
}
有趣的观察结果:

  • 它更有可能影响较大的实体(具有更多属性),但偶尔也会影响较小的实体
  • 生成的SQL始终具有与映射属性相同的列数
  • SQL上的列与映射类上的映射属性的顺序相同
  • 错误列将替换现有列
  • 错误列是其他映射实体中的有效列
  • 受影响实体与列错误实体之间没有关系
其他详细信息:

  • .NET版本:4.0
  • NHibernate版本:3.3.3.400
  • 按代码映射:NHibernate.Mapping.ByCode
  • 按代码配置:NHibernate.Cfg
加载映射

var mapper = new ModelMapper();

foreach (var assembly in resolver.GetAssemblies()) // resolver is a class that gets all the assemblies for the current application
    mapper.AddMappings(assembly.GetExportedTypes());

var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

return mapping;
会话工厂配置

ORA-00904: "CLINICA0_"."FATURADEPARCELAMENTO": invalid identifier
var configure = new Configuration();
configure.DataBaseIntegration(x =>
                                  {
                                      x.Dialect<Oracle10gDialect>();  // Custom class
                                      x.ConnectionString = ConnectionString;
                                      x.BatchSize = 100;
                                      x.Driver<OracleMultiQueryDataClientDriver>();  // Custom class
                                      x.MaximumDepthOfOuterJoinFetching = 10;
                                      x.Timeout = 250;
                                      x.PrepareCommands = true;
                                      x.HqlToSqlSubstitutions = "true 'S', false 'N', yes 'S', no 'N'";
                                      x.LogFormattedSql = true;
                                      x.LogSqlInConsole = true;
                                      x.AutoCommentSql = true;
                                      x.IsolationLevel = IsolationLevel.ReadCommitted;
                                      x.ConnectionProvider<ConnectionProvider>();  // Custom class
                                  });
configure.Properties.Add(new KeyValuePair<string, string>("hibernate.command_timeout", "250"));
configure.Proxy(x => x.ProxyFactoryFactory<NHibernate.Bytecode.DefaultProxyFactoryFactory>());
configure.LinqToHqlGeneratorsRegistry<LinqToHqlGeneratorsRegistry>();
configure.CurrentSessionContext<NHibernate.Context.WebSessionContext>();
var mapping = GetMappings(); // Method showed above
mapping.autoimport = false;
configure.AddMapping(mapping);
var listener = new AuditEventListener();
configure.EventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { listener };
configure.EventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { listener };
configure.SessionFactory().GenerateStatistics();
return configure;
var configure=新配置();
configure.DataBaseIntegration(x=>
{
x、 方言();//自定义类
x、 ConnectionString=ConnectionString;
x、 批量大小=100;
x、 驱动程序();//自定义类
x、 最大depthofoutherjoinfetching=10;
x、 超时=250;
x、 PrepareCommands=true;
x、 hqltosqlssubstitutions=“true'S',false'N',yes'S',no'N';
x、 LogFormattedSql=true;
x、 logsqlincole=true;
x、 AutoCommentSql=true;
x、 IsolationLevel=IsolationLevel.ReadCommitted;
x、 ConnectionProvider();//自定义类
});
添加(新的KeyValuePair(“hibernate.command_timeout”,“250”);
configure.Proxy(x=>x.ProxyFactoryFactory());
configure.LinqToHqlGeneratorsRegistry();
configure.CurrentSessionContext();
var mapping=GetMappings();//方法如上所示
mapping.autoimport=false;
configure.AddMapping(映射);
var listener=新的AuditEventListener();
configure.EventListeners.PostInsertEventListeners=new IPostInsertEventListener[]{listener};
configure.EventListeners.postopdateeventlisteners=new-iposupdateeventlistener[]{listener};
configure.SessionFactory().GenerateStatistics();
返回配置;

检查您的查询日志,看看它运行的是什么类型的查询,在您的sql中,从那里您可以发现问题。

看起来“信用卡支付”FATURADEPARCELAMENTO是您的“贷方”对象prestado上的一个属性,如果是这种情况,它需要是一个引用,而不是映射中的属性。希望这能帮助你,或者至少能帮你找到正确的方向

引用将取代您的行 属性(x=>x.HandlePrestador,map=>map.Column(“PRESTADOR”); 而且会很接近
参考资料(x=>x.HandlePrestador)

我在NHibernate用户Google Groups论坛上问了同样的问题,有人认为他们已经找到了根本原因(并提出了解决方案):

问题代码位于PropertyPath.Equals(PropertyPath)中,它试图仅使用哈希代码来确定相等性。对于较小的代码基,这可以作为默认对象使用。GetHashCode()返回一个顺序对象索引。但是,在垃圾收集之后,这些索引会被重用,因为最终确定的对象会被删除并创建新对象…这会导致多个对象获得相同的哈希代码…一旦垃圾收集开始,属性路径有机会共享相同的哈希代码,这意味着它们最终会将冲突属性的自定义项混合在一起,从而导致错误的列名

如果要修复此错误,可以修补NH源代码:

如果您有自己的NH源代码副本,您可以通过更改NHibernate/Mapping/ByCode/PropertyPath.cs行#66来修复此错误,方法是:

返回hashCode==other.GetHashCode()

致:

返回hashCode==other.GetHashCode()&&ToString()==other.ToString()


有关此问题的详细信息,请查看Google Group。

是否有多个实体映射到同一数据库表?有一些实体,但本例中没有。Clinica是唯一映射到CLI_Clinica表的实体。它是否总是引用同一个无效列?更多问题:是否可以发布冲突解决程序的代码?你是CLINICA的子类吗?有完全相同的问题。你找到解决办法了吗?
var mapper = new ModelMapper();

foreach (var assembly in resolver.GetAssemblies()) // resolver is a class that gets all the assemblies for the current application
    mapper.AddMappings(assembly.GetExportedTypes());

var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

return mapping;
var configure = new Configuration();
configure.DataBaseIntegration(x =>
                                  {
                                      x.Dialect<Oracle10gDialect>();  // Custom class
                                      x.ConnectionString = ConnectionString;
                                      x.BatchSize = 100;
                                      x.Driver<OracleMultiQueryDataClientDriver>();  // Custom class
                                      x.MaximumDepthOfOuterJoinFetching = 10;
                                      x.Timeout = 250;
                                      x.PrepareCommands = true;
                                      x.HqlToSqlSubstitutions = "true 'S', false 'N', yes 'S', no 'N'";
                                      x.LogFormattedSql = true;
                                      x.LogSqlInConsole = true;
                                      x.AutoCommentSql = true;
                                      x.IsolationLevel = IsolationLevel.ReadCommitted;
                                      x.ConnectionProvider<ConnectionProvider>();  // Custom class
                                  });
configure.Properties.Add(new KeyValuePair<string, string>("hibernate.command_timeout", "250"));
configure.Proxy(x => x.ProxyFactoryFactory<NHibernate.Bytecode.DefaultProxyFactoryFactory>());
configure.LinqToHqlGeneratorsRegistry<LinqToHqlGeneratorsRegistry>();
configure.CurrentSessionContext<NHibernate.Context.WebSessionContext>();
var mapping = GetMappings(); // Method showed above
mapping.autoimport = false;
configure.AddMapping(mapping);
var listener = new AuditEventListener();
configure.EventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { listener };
configure.EventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { listener };
configure.SessionFactory().GenerateStatistics();
return configure;