Pregunta

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!

¿Fue útil?

Solución

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?

Otros consejos

RacerNerd,

Needing the proper accessors:

public string productCode { get; set; }; 

vs

public string productCode;

I missed that! Good catch.

I believe the reason for the explicit getter and setters is not only to follow the convention of Entity Framework POCOs, but also I believe when you explicitly use getters and setters, you are telling the CLR the class member is a property vs a public variable. On the surface, they function the same. But if PetaPoco is using reflection to match class properties to fields, that may be why it is required

I just noticed that you just have a single attribute mapped to a field in your table. It is marked as both the Scope and Primary Key. The Scope is the unit at which you cache your item sets. It doesn't make sense to make it the same as your Primary Key. Usually it's a portal ID, module ID, category ID, or something representing a set of product records.

That said, try removing the Scope attribute entirely - at least for now. Also, does your table have a field called "productCode". I believe that PetaPoco is case-sensitive so it has to match exactly. Otherwise you need to add the field mapping attribute [ColumnName("Product_Code")] above your productCode member to match the field name in your table.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top