2015-08-16 60 views
3

我试图为以下代码的一般方法:创建一个通用的方法

foreach (var glitter in glitterpurchase.GlitterPurchaseDetails) 
{ 
    var glitterInventory = _db.GlitterInventoriesRepository.GetAll(m => m.GlitterId == glitter.GlitterId); 
    if (!glitterInventory.Any()) 
    { 
     var newInventory = new GlitterInventory 
     { 
      GlitterId = glitter.GlitterId, 
      Quantity = glitter.Quantity, 
      TotalAmount = (decimal)glitter.Quantity * glitter.UnitPrice, 
      UnitPrice = glitter.UnitPrice, 
      CreatedBy = User.Identity.Name, 
      CreatedDate = DateTime.Now, 
     }; 
     _db.GlitterInventoriesRepository.Insert(newInventory); 
    } 
    else      
    { 
     var updateInventory = glitterInventory.First(); 
     updateInventory.Quantity += glitter.Quantity; 
     updateInventory.TotalAmount += (decimal)glitter.Quantity * glitter.UnitPrice; 
     updateInventory.UnitPrice = (decimal)updateInventory.Quantity/updateInventory.TotalAmount; 
     updateInventory.UpdatedBy = User.Identity.Name; 
     updateInventory.UpdatedDate = DateTime.Now; 
     _db.GlitterInventoriesRepository.Update(updateInventory); 
    } 
} 

上面的代码只是简单的更新库存。我想制作一个通用方法,以便我可以调用该方法并更新不同项目(类)的库存。我不擅长与泛型和研究我写了下面的代码之后:

public virtual void UpdateInventory<PurchasedEntity, Inventory>(IEnumerable<PurchasedEntity> purchaseDetails, GenericRepository<Inventory> inventory, Expression<Func<Inventory, bool>> filterForInventory) 
      where PurchasedEntity : class 
      where Inventory : class 

{ 
    foreach (var item in purchaseDetails) 
    { 
     var glitterInventory = inventory.GetAll(filterForInventory); 
     if (!glitterInventory.Any()) 
     { 
      var newInventory = (Inventory)Activator.CreateInstance(typeof(Inventory), new object[] 
      { 
       GlitterId = item.GlitterId, 
       Quantity = item.Quantity, 
       TotalPrice = (decimal)item.Quantity * item.UnitPrice, 
       UnitPrice = item.UnitPrice, 
       CreatedBy = User.Identity.Name, 
       CreatedDate = DateTime.Now, 
      }); 

      inventory.Insert(newInventory); 
     } 
     else 
     { 
      var updateInventory = glitterInventory.First(); 
      updateInventory.Quantity += item.Quantity; 
      updateInventory.TotalAmount += (decimal)item.Quantity * item.UnitPrice; 
      updateInventory.UnitPrice = (decimal)updateInventory.Quantity/updateInventory.TotalAmount; 
      updateInventory.UpdatedBy = User.Identity.Name; 
      updateInventory.UpdatedDate = DateTime.Now; 
      inventory.Update(updateInventory); 
     } 
    } 
} 

的问题是,我收到以下错误:

'PurchasedEntity' does not contain a definition for 'GlitterId' and no extension method 'GlitterId' accepting a first argument of type 'PurchasedEntity' could be found (are you missing a using directive or an assembly reference?) 

如何删除这个错误,并得到该类的属性一般?

我甚至不知道我写的代码是否有用,如果你能改善它,那就太好了,那太棒了。谢谢。

+1

你已经定义了一个泛型参数约束'where PurchasedEntity:class',这意味着它可以使用这个泛型参数的任何类型。因此,当使用* item *变量时,泛型方法只能使用Object类提供的方法,属性和字段 - 因为Object类是任何类型中最不常见的分母...您需要指定约束一种只限于声明那些GlitterId,Quantity,UnitPrice等属性的(基类)类的方法。然后编译器会接受这段代码。 – elgonzo

+0

@elgonzo我可以用Quantity,TotalPrice,UnitPrice,CreatedBy,CreatedDate创建一个基类,但GlitterId应该是通用的,因为GlitterId可以是PowderId,ColorId等。我有很多库存项目,我正在尝试编写一个可用于所有库的通用方法。 –

+0

GlitterId是属性的名称,而不是类型。您不能使用通用参数来“交换”属性的名称... – elgonzo

回答

1

我假设并非每个PurchasedEntity都有一个GlitterId(并且可能不应取决于您的域)。因此,确定适当的Id财产上PurchasedEntity(或更好,但其解压缩到一个接口):

interface IPurchasedEntity{ 
    Guid Id {get;} 
} 

更新GlitterInventory实施IPurchasedEntity

public class GlitterInventory : IPurchasedEntity{ 
    Guid IPurchasedEntity.Id { get{ return GlitterId; }} 
} 

然后你UpdateInventory方法应该读Id,而不是GlitterId

public virtual void UpdateInventory<PurchasedEntity, Inventory>(
    IEnumerable<PurchasedEntity> purchaseDetails, 
    GenericRepository<Inventory> inventory, 
    Expression<Func<Inventory, bool>> filterForInventory) 
     where PurchasedEntity : IPurchasedEntity, class 
     where Inventory : IPurchasedEntity, class, new() 
{ 
    foreach (var item in purchaseDetails) 
    { 
     var inventory = new Inventory(); 
     inventory.Id = item.Id; 
     // if you have more standard fields, define them in IPurchasedEntity 
    } 
} 

更新:尝试从PurcahsedEntityInventory推断出您的域名后,调用IPurchasedEntityIInventory代替并定义您的通用属性可能更有意义。

+0

非常感谢,同样是由@elgonzo建议,你可以看到我们的聊天。我接受这个答案,但如果elgonzo在这里写了一个答案,那么我会将这个答案标记为答案,因为他真的花了一些时间来解决这个问题。 –