2

I use Entity Framework 4.3.1.0

SQL Server 2008 Express

I have Views

SELECT  dbo.Dealers.Name AS DealerName, 
        dbo.Dealers.LogoImage, 
        dbo.DealersProducts.Price, 
        dbo.DealersProducts.StatusType, 
        dbo.Products.Description,                       
        dbo.Products.Name, 
        dbo.DealersProducts.DealerId, 
        dbo.Products.Id 
FROM dbo.Dealers 
INNER JOIN
dbo.DealersProducts 
ON dbo.Dealers.Id = dbo.DealersProducts.DealerId 
INNER JOIN                       
dbo.Products 
ON dbo.DealersProducts.ProductId = dbo.Products.Id

and I have Entity

public class DealerViews : BasePersistentEntity
{
    public int DealerId { get; set; }

    public string DealerName { get; set; }

    public string LogoImage { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public decimal Price { get; set; }

    public int StatusType { get; set; }
}

This View I use for return dealer ho have request product. When I request SQL query in SQL Manager I gate correct result but in Entity Framework I get strange result. Examples

SQL result

Dealer 1

Dealer 2

Entity Framework result

Dealer 1

Dealer 1

Code in controller

public ActionResult ShowProductDealers(int id)
{
    var dealer = this.dealerService.GetDealerByProductId(id);

    return this.PartialView("ShowProductDealers", dealer);
}

Code in Service

public IEnumerable<DealerViews> GetDealerByProductId(int id)
{
    return this.repositoryViews.All.Where(item => item.Id == id);
}

Code in repository

public class SGNRepository<T> where T : BasePersistentEntity
{
    public readonly SGNContext<T> Context = new SGNContext<T>();

    public IQueryable<T> All
    {
        get { return this.Context.Table; }
    }

    public IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = this.Context.Table;
        return includeProperties.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
    }

    public T Find(int id)
    {
        return this.Context.Table.Find(id);
    }

    public void InsertOrUpdate(T item)
    {
        if (item.Id == default(int))
        {
            // New entity
            this.Context.Table.Add(item);
        }
        else
        {
            // Existing entity
            this.Context.Entry(item).State = EntityState.Modified;
        }

        this.Save();
    }

    public void Delete(int id)
    {
        var item = this.Context.Table.Find(id);
        this.Context.Table.Remove(item);
        this.Save();
    }

    private void Save()
    {
        this.Context.SaveChanges();
    }
Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654
Hryhorii
  • 875
  • 2
  • 13
  • 36

1 Answers1

5

It is problem with your mapping. What column did you select as primary key for the entity? I expect that in this case you have Product.Id as primary key and this product has many dealers.

EF uses primary key as unique identification. Each record must be uniquely identified. If EF loads record and it doesn't have its unique identification in its internal identity map, it creates and entity instance from that record and put it to identity map. Next time it gets the record with the same unique identification it will not create a new entity instance but instead it uses instance stored in identity map. That is the reason why you get to same results.

Btw. your repository is wrong because you cannot insert, delete or update entities created from view (unless you map stored procedures or custom SQL commands for all these operations) so it should not expose such methods.

Another point is why do you have repository and service when it wraps just single call = no added value and no reason to do that especially when your repository supports only simple CRUD operations on one entity type.

Community
  • 1
  • 1
Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654