jgauffin / Griffin.Framework

Application framework for Business Applications
http://griffinframework.net
168 stars 62 forks source link

Griffin.Data.Mapper question #72

Closed kadyrkulovr closed 8 years ago

kadyrkulovr commented 8 years ago

i have 2 entity classes:

public class Document
{
    public int Id { get; set; }
    public DocumentCategory DocumentCategory { get; set; }
}

public class DocumentCategory
{
    public int Id { get; set; }
    public string Description { get; set; }
}

1 Mapper class

public class SimpleMapper : EntityMapper<document>
{
    // My questions is - What i need to write here to bind 
    // db column [CategoryId] to property [Document.DocumentCategory.Id]?
}

repository

public class DocumentRepository
{
    private AdoNetUnitOfWork _unitOfWork;

    public DocumentRepository(IUnitOfWork uow)
    {
        //hide
    }

    public async Task<document> GetAsync(int id)
    {
        using (var cmd = _unitOfWork.CreateCommand())
        {
            cmd.CommandText = "Document.GetDocumentById";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("id", id);

            return await cmd.FirstOrDefaultAsync<document>();      // exception goes here
        }
    }
}

stored precedure result

Id | CategoryId 1 | 1

Exception:

Griffin.Data.Mapper.MappingException: CompanyName.DocFlow.DAL.Entities.Document: Failed to cast column value to property value for 'CompanyName.DocFlow.DAL.Entities.Document.DocumentCategory'. ---> System.IndexOutOfRangeException: DocumentCategory

jgauffin commented 8 years ago

Like this:

public class SimpleMapper : EntityMapper<Document>
{
    public SimpleMapper()
    {
        Property(x => x.DocumentCategory)
            .ColumnName("CategoryId")
            .ToPropertyValue(x => new DocumentCategory { Id = (int)x });
    }
}
kadyrkulovr commented 8 years ago

Hello! now i need to map all properties of DocumentCategory (not just DocumentCategory.Id) How can i do it with your mapper? this solution map only last property:

public class SimpleMapper : EntityMapper<Document>
{
    public SimpleMapper()
    {
        Property(x => x.DocumentCategory)
            .ColumnName("CategoryId")
            .ToPropertyValue(x => new DocumentCategory { Id = (int)x });
        Property(x => x.DocumentCategory)
            .ColumnName("CategoryDescription")
            .ToPropertyValue(x => new DocumentCategory { Description= (string)x });
        //other properties...
    }
}

update: stored procedure result:

Id Name DocumentCategoryId DocumentCategoryName
1 myDoc1 1 FirstCategory

i tried like this

public void Map(IDataRecord source, object destination)
        {
            var doc= (Document)destination;
            doc.Id = (int)source["Id"];
            doc.Name = source["Name"].ToString();
            doc.DocumentCategory.Id = (int)source["DocumentCategoryId"];
            doc.DocumentCategory.Name = source["DocumentCategoryName"].ToString();
        }

but fail with exception

Failed to cast column value to property value for 'ProjectName.Core.Entities.Document.DocumentCategory'.

jgauffin commented 8 years ago

There is no support.

There are two types two queries:

Searches

in these queries you just want to find the correct item and rarely want all the details. Thus a limited SQL query with typically information from the main table will do.

Getting entity details.

(i do the below in my repository method) For these query I first query the main table (document) to get the entity details. Then I query the child tables (documentcategory) to get all the details. Then I just add them to the main entity before returning.

var entity = _uow.First<Document>("id = @0", id);
var categories = _uow.ToList<DocumentCategory>("DocumentId = @0", id);
entity.Categories = categories;

Adding that functionality to the library would would make it a lot more complex.

kadyrkulovr commented 8 years ago

Thank you!