2

我使用实体框架 4.3.1.0

SQL Server 2008 速成版

我有意见

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

我有实体

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

此视图用于退货经销商有要求的产品。当我在 SQL 管理器中请求 SQL 查询时,我选择了正确的结果,但在实体框架中我得到了奇怪的结果。例子

SQL 结果

经销商 1

经销商 2

实体框架结果

经销商 1

经销商 1

控制器中的代码

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

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

服务中的代码

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

存储库中的代码

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();
    }
4

1 回答 1

5

你的映射有问题。您选择了哪一列作为实体的主键?我希望在这种情况下您拥有Product.Id主键,并且该产品有很多经销商。

EF 使用主键作为唯一标识。每条记录都必须唯一标识。如果 EF 加载记录并且在其内部身份映射中没有其唯一标识,它会从该记录创建实体实例并将其放入身份映射。下次它获取具有相同唯一标识的记录时,它不会创建新的实体实例,而是使用存储在身份映射中的实例。这就是你得到相同结果的原因。

顺便提一句。您的存储库是错误的,因为您无法插入、删除或更新从视图创建的实体(除非您为所有这些操作映射存储过程或自定义 SQL 命令),因此它不应公开此类方法。

另一点是为什么你有存储库和服务,当它只包装单个调用 = 没有附加值并且没有理由这样做时,特别是当你的存储库仅支持对一种实体类型的简单 CRUD 操作时。

于 2012-05-26T14:19:33.623 回答