0

I am creating a module for use in DNN 7+ and would like to use DAL2 for data access but am having some problems selecting items from the database.

My code appears to be connecting to the database successfully but the queries that are generated by DAL2 do not include the names of the fields in the database table. I an running an SQL Server Profiler to watch what gets to the database and see queries that start with "SELECT NULL FROM Product...". I expect to see "SELECT * FROM Product..." or "SELECT ProductCode FROM Product..."

For the purposes of isolating the problem and being able to include a full code sample, I have worked my test down to the following: I have a Product.cs file:

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

I have a ProductRepository.cs file:

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

I use these two files in my view with the following code:

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

While running this code, I monitor using the SQL Server Profiler and see that the following query is executed:

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

I don't know why the select query above is selecting NULL. I am expecting a list of product fields from the Product.cs file, or the * character.

My database field definition (as seen from the tree view of the Microsoft SQL Server Management Studio) for the productCode is:

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

I am connecting to an external database and the data is not connected with a specific module or portal. That is why I specify "productCode" as the Scope. I am not sure what the proper use of Scope is when the data is not tied to the portal or module. To make sure the problem was not connected to the Scope attribute in the Product.cs file I tested with the Scope variable set to "PortalId", "ModuleId", "productCode", and "Nothing". All of these values resulted in the same query showing up in the SQL Server Profiler.

I also tested by removing the Scope attribute entirely. When the Scope attribute was not included I saw the following query in the SQL Server Profiler:

SELECT NULL FROM [Product]

I am not sure why the WHERE clause was removed when the Scope attribute was excluded, but that is what test results showed.

These tests with the Scope attribute lead me to believe it is not related to the "SELECT NULL" problem I am seeing but I wanted to include it here for completeness.

Can anyone help, why is this creating a select with NULL and how do I get it to select my data?

Thanks!

4

3 回答 3

1

I found an answer but would like a little help understanding why this works. First, to get the data column to connect, I changed the Product.cs class to this:

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

The difference here is the addition of the get and set accessors. This is confusing to me as I thought the previously used line

public string productCode;

would be functionally equivalent to

public string productCode { get; set; };

in this context. I thought 'get' and 'set' were not needed unless access to the variable was going to be limited to one of those operations, or if more extensive processing needed to happen while setting or getting the protected value.

Am I missing something in my understanding of get and set or am I understanding this correctly? Are the get and set only required here to be compatible with DAL2?

于 2013-10-08T23:07:36.140 回答
1

赛车手,

需要适当的访问器:

public string productCode { get; set; }; 

对比

public string productCode;

我错过了!接得好。

我相信显式 getter 和 setter 的原因不仅是为了遵循实体框架 POCO 的约定,而且我相信当您显式使用 getter 和 setter 时,您是在告诉 CLR 类成员是属性而不是公共变量。从表面上看,它们的功能相同。但如果 PetaPoco 使用反射将类属性与字段匹配,这可能就是需要它的原因

于 2013-10-08T23:59:17.053 回答
0

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

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

于 2013-10-08T22:53:45.473 回答