0

我正在创建一个用于DNN 7+的模块,并且希望使用DAL2进行数据访问,但是在从数据库中选择项目时遇到了一些问题。为什么DAL2查询缺少字段名称并显示SELECT NULL?

我的代码似乎已成功连接到数据库,但由DAL2生成的查询不包括数据库表中的字段名称。我运行一个SQL Server Profiler来观察到达数据库的内容并查看以“SELECT NULL FROM Product ...”开头的查询。我希望看到“SELECT * FROM产品...”或“选择产品代码从产品...”

为分离的问题,并能够提供一个完整的代码示例的目的,我曾在我的测试下来以下几点: 我有一个Product.cs文件:

using System.Web.Caching; 
using DotNetNuke.ComponentModel.DataAnnotations; 

namespace MyModule.Components 
{ 
    [TableName("Product")] 
    [PrimaryKey("productCode")] 
    [Cacheable("MYMODULE_Product_", CacheItemPriority.Default, 20)] 
    [Scope("productCode")] //different values here did not change the result. 
    public class Product 
    { 
     public string productCode; 
    } 
} 

我有一个ProductRepository.cs文件:

using DotNetNuke.Data; 

namespace MyModule.Components 
{ 
    public class ProductRepository 
    { 
     private const string EXTERNAL_DB_CONNECTION_STRING = "MY_DB_CONNECTIONSTRING_NAME"; 

     public Product GetProduct(string productCode) 
     { 
      Product t; 
      using (IDataContext ctx = DataContext.Instance(EXTERNAL_DB_CONNECTION_STRING)) 
      { 
       var rep = ctx.GetRepository<Product>(); 
       t = rep.GetById(productCode); 
      } 
      return t; 
     } 
    } 
} 

我在用下面的代码视图中使用这两个文件:

ProductRepository productRepo = new ProductRepository();  
Product product = (Product)productRepo.GetProduct("MYCODE"); 

虽然运行此代码,我监视器使用SQL Server事件探查,看到下面的查询被执行:

exec sp_executesql N'SELECT NULL FROM [Product] WHERE [productCode][email protected]',N'@0 nvarchar(4000)',@0=N'MYCODE' 

我不知道为什么上面的选择查询选择NULL。我期待Product.cs文件或*字符中的产品字段列表。

我的数据库字段定义为产品代码(如从Microsoft SQL Server Management Studio中的树状视图中看到)是:

productCode(PK, varchar(50), not null) 

我连接到外部数据库和数据不与连接特定的模块或门户。这就是为什么我将“productCode”指定为范围的原因。我不确定当数据没有绑定到门户或模块时Scope的正确用法是什么。为了确保问题没有连接到我使用设置为“PortalId”,“ModuleId”,“productCode”和“Nothing”的Scope变量测试的Product.cs文件中的Scope属性。所有这些值都导致在SQL Server Profiler中显示相同的查询。

我也通过完全删除Scope属性进行测试。当没有被列入该范围的属性,我看到在SQL Server Profiler中以下查询:

SELECT NULL FROM [Product] 

我不知道为什么当scope属性被排除去除WHERE子句,但是这结果表明什么测试。

这些测试用scope属性导致我相信它是不相关的“选择空”问题,我看到了,但我想在这里的完整性包括它。

任何人都可以帮忙,为什么这创建一个选择与NULL,我如何得到它来选择我的数据?

谢谢!

回答

1

我找到了一个答案,但希望有一点帮助,理解为什么这个工程。 第一,得到数据列连接时,我改变了Product.cs类这样的:

using System.Web.Caching; 
using DotNetNuke.ComponentModel.DataAnnotations; 
namespace MyModule.Components 
{ 
    [TableName("Product")] 
    [PrimaryKey("productCode")] 
    [Cacheable("MYMODULE_Product_", CacheItemPriority.Default, 20)] 
    [Scope("productCode")] //tried different values here and nothing changed but excluding this caused more problems 
    public class Product 
    { 
     public string productCode { get; set; }; 
    } 
} 

这里的区别是增加了get和set访问的。这是混淆了我,因为我想到了以前使用的线

public string productCode; 

在功能上等同于

public string productCode { get; set; }; 

在这方面。我认为'get'和'set'是不需要的,除非将访问变量限制在其中一个操作中,或者在设置或获取受保护值时需要进行更广泛的处理。

我在理解get和set时是否缺少某些东西,或者我是否正确理解了这一点? get和set仅在这里需要与DAL2兼容吗?

0

我只注意到你只有一个属性映射到表中的一个字段。它被标记为范围和主键。范围是您缓存项目集的单位。将它与主键相同是没有意义的。通常它是门户ID,模块ID,类别ID或表示一组产品记录的东西。

也就是说,尝试完全删除Scope属性 - 至少现在。此外,你的表是否有一个名为“productCode”的字段。我相信PetaPoco是区分大小写的,因此它必须完全匹配。否则,您需要在productCode成员上添加字段映射属性[ColumnName(“Product_Code”)]以匹配表中的字段名称。

+0

我在OP中提到在Scope属性中使用了几个不同的值。当我完全删除范围时,WHERE子句不包含在SQL中。我不知道为什么会发生这种情况,并希望我做到了。由于我的数据未连接到模块或门户,因此我不确定适用于范围的适当值。我所知道的是,省略Scope属性似乎不起作用,并且我包括的任何其他值(在我的有限测试中)都不会影响SQL。 – RacerNerd

1

RacerNerd,

孤男寡女适当的存取:

public string productCode { get; set; }; 

VS

public string productCode; 

我错过了!接得好。

我相信明确的getter和setter的原因不仅是遵循实体框架POCO的惯例,而且我相信当你明确使用getters和setters时,你告诉CLR类成员是一个属性vs一个公共变量。表面上,它们的功能相同。但是,如果PetaPoco使用反射来匹配类属性和字段,那么这可能就是为什么它是必需的

+0

此评论并不是说谢谢。 ;) – RacerNerd

相关问题