Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/19/13 15:25:31 (11 years ago)
Author:
spimming
Message:

#1888:

  • Model classes implement new interface to track current state of entity
  • Mark EntityState property as 'not mapped'
  • Set hook to initialize entity as unchanged
  • Extension method for DbContext to apply changes only on modified entity
Location:
branches/OaaS/HeuristicLab.Services.Optimization.Billing
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/BillingEngine/BillingEngine.cs

    r9641 r9645  
    8989              usageCharges.Invoice = invoice;
    9090              usageCharges.Product = billingService.GetProductByName("Oaas Usage Charges").First();
    91               usageCharges.ProductPrice = -999.99;
     91              usageCharges.ProductPrice = 999.99;
    9292              usageCharges.Quantity = 1;
    9393              invoice.InvoiceLines.Add(usageCharges);
     
    102102              UpdateBillingState(order);
    103103              billingService.UpdateOrder(order);
     104              billingService.SaveInvoice(invoice);
    104105            }
    105106          }
     
    120121      }
    121122
     123      order.LastBillableDay = currentDate;
    122124      DateTime nextBillingDay = CalculateNextBillingDate(order);
    123125
     
    130132        order.NextBillableDay = nextBillingDay;
    131133      }
     134
     135      order.EntityState = State.Modified;
    132136    }
    133137
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/Business/BillingService.cs

    r9619 r9645  
    4242      //TODO: Authentication
    4343      //TODO: Enable Transaction
    44       BillingDao.AddOrder(order);
     44      BillingDao.InsertOrUpdateOrder(order);
    4545    }
    4646
     
    5959
    6060    public void UpdateOrder(Order order) {
    61       throw new System.NotImplementedException();
     61      //TODO: Authentication
     62      //TODO: Enable Transaction
     63      BillingDao.InsertOrUpdateOrder(order);
    6264    }
    6365
     
    7577      //TODO: Authentication
    7678      //TODO: Enable Transaction
    77       BillingDao.AddUser(user);
     79      BillingDao.InsertOrUpdateUser(user);
    7880    }
    7981
     
    104106    }
    105107
     108    public void SaveInvoice(Invoice invoice) {
     109      //TODO: Authentication
     110      //TODO: Enable Transaction
     111      BillingDao.InsertOrUpdateInvoice(invoice);
     112    }
     113
    106114    #endregion
    107115  }
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/Business/MockupBillingService.cs

    r9619 r9645  
    134134    }
    135135
     136    public void SaveInvoice(Model.Invoice invoice) {
     137      throw new NotImplementedException();
     138    }
     139
    136140    #endregion
    137141  }
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/DataAccess/BillingContext.cs

    r9641 r9645  
    22using System.Collections.Generic;
    33using System.Data.Entity;
     4using System.Data.Entity.Infrastructure;
    45using System.Data.Entity.ModelConfiguration;
    56using System.Data.Entity.ModelConfiguration.Conventions;
     7using HeuristicLab.Services.Optimization.Billing.Interfaces;
    68using HeuristicLab.Services.Optimization.Billing.Model;
    79
     
    2830    public BillingContext(string connectionString)
    2931      : base(connectionString) {
     32
     33      Database.SetInitializer(new HeuristicLab.Services.Optimization.Billing.DataAccess.BillingContext.BillingContextInitiliazer());
     34
     35      // Hook up event to mark existing entities as Unchanged
     36      ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += (sender, args) => {
     37        var entity = args.Entity as IObjectWithState;
     38        if (entity != null) {
     39          entity.EntityState = State.Unchanged;
     40        }
     41      };
     42
    3043      this.Configuration.LazyLoadingEnabled = false;
    3144      this.Configuration.ProxyCreationEnabled = false;
     
    3346
    3447    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
     48      modelBuilder.Configurations.Add(new ContactInformationConfiguration());
     49      modelBuilder.Configurations.Add(new PaymentInformationConfiguration());
     50      modelBuilder.Configurations.Add(new ProductConfiguration());
    3551      modelBuilder.Configurations.Add(new OrderConfiguration());
    3652      modelBuilder.Configurations.Add(new OrderLineConfiguration());
     
    4763    #region EntityTypeConfigurations
    4864
     65    private class ContactInformationConfiguration : EntityTypeConfiguration<ContactInformation> {
     66      internal ContactInformationConfiguration() {
     67        this.Ignore(ci => ci.EntityState);
     68      }
     69    }
     70
     71    private class PaymentInformationConfiguration : EntityTypeConfiguration<PaymentInformation> {
     72      internal PaymentInformationConfiguration() {
     73        this.Ignore(pi => pi.EntityState);
     74      }
     75    }
     76
     77    private class ProductConfiguration : EntityTypeConfiguration<Product> {
     78      internal ProductConfiguration() {
     79        this.Ignore(p => p.EntityState);
     80      }
     81    }
     82
    4983    private class OrderConfiguration : EntityTypeConfiguration<Order> {
    5084      internal OrderConfiguration() {
     85        this.Ignore(o => o.EntityState);
    5186        this.HasRequired(o => o.User).WithMany().HasForeignKey(o => o.UserId);
    5287        // TODO: OrderState?
     
    5691    private class OrderLineConfiguration : EntityTypeConfiguration<OrderLine> {
    5792      internal OrderLineConfiguration() {
     93        this.Ignore(ol => ol.EntityState);
    5894        this.HasRequired(ol => ol.Order).WithMany(o => o.OrderLines).HasForeignKey(ol => ol.OrderId).WillCascadeOnDelete(true);
    5995        this.HasRequired(ol => ol.Product).WithMany().HasForeignKey(ol => ol.ProductId);
     
    6399    private class InvoiceConfiguration : EntityTypeConfiguration<Invoice> {
    64100      internal InvoiceConfiguration() {
     101        this.Ignore(i => i.EntityState);
    65102        this.HasRequired(i => i.User).WithMany().HasForeignKey(i => i.UserId);
    66103        this.HasRequired(i => i.Order).WithMany(o => o.Invoices).HasForeignKey(i => i.OrderId);
     
    70107    private class InvoiceLineConfiguration : EntityTypeConfiguration<InvoiceLine> {
    71108      internal InvoiceLineConfiguration() {
     109        this.Ignore(i => i.EntityState);
    72110        this.HasRequired(il => il.Invoice).WithMany(i => i.InvoiceLines).HasForeignKey(il => il.InvoiceId).WillCascadeOnDelete(true);
    73111        this.HasRequired(il => il.Product).WithMany().HasForeignKey(il => il.ProductId);
     
    77115    private class UsageRecordConfiguration : EntityTypeConfiguration<UsageRecord> {
    78116      internal UsageRecordConfiguration() {
     117        this.Ignore(ur => ur.EntityState);
    79118        this.HasRequired(ur => ur.User).WithMany().HasForeignKey(ur => ur.UserId);
    80119        this.HasRequired(ur => ur.Product).WithMany().HasForeignKey(ur => ur.ProductId);
     
    84123    private class UserConfiguration : EntityTypeConfiguration<User> {
    85124      internal UserConfiguration() {
     125        this.Ignore(u => u.EntityState);
    86126        this.HasMany(u => u.PaymentInformation).WithRequired(pi => pi.User).HasForeignKey(pi => pi.UserId);
    87127        this.HasRequired(u => u.ContactInformation).WithMany().HasForeignKey(u => u.ContactInformationId);
     
    166206          BillingPeriod = BillingPeriod.Monthly,
    167207        };
     208
    168209        OrderLine ol1 = new OrderLine() {
    169210          Order = o1,
     
    172213          Quantity = 1
    173214        };
     215
    174216        o1 = context.Orders.Add(o1);
    175217        ol1 = context.OrderLines.Add(ol1);
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/DataAccess/BillingDao.cs

    r9641 r9645  
    22using System;
    33using System.Collections.Generic;
     4using System.Data;
    45using System.Data.Entity;
    56using System.Linq;
    67using System.Linq.Expressions;
    78using HeuristicLab.Services.Optimization.Billing.Model;
     9using HeuristicLab.Services.Optimization.Billing.Utils;
    810namespace HeuristicLab.Services.Optimization.Billing.DataAccess {
    911  public class BillingDao {
     
    1618    }
    1719
    18     private delegate T ExecuteWithContextDelegate<T>(BillingContext context);
    19     private delegate void ExecuteWithContextDelegate(BillingContext context);
    20 
    21     private void ExecuteWithContext(ExecuteWithContextDelegate call) {
    22       BillingContext context = null;
    23       try {
    24         using (context = CreateContext()) {
    25           call(context);
    26         }
    27       }
    28       finally {
    29         if (context.Database.Connection.State == System.Data.ConnectionState.Open) {
    30           context.Database.Connection.Close();
    31         }
    32       }
    33     }
    34 
    35     private T ExecuteWithContext<T>(ExecuteWithContextDelegate<T> call) {
    36       BillingContext context = null;
    37       try {
    38         using (context = CreateContext()) {
    39           T result = call(context);
    40           return result;
    41         }
    42       }
    43       finally {
    44         if (context.Database.Connection.State == System.Data.ConnectionState.Open) {
    45           context.Database.Connection.Close();
    46         }
    47       }
    48     }
    49 
    5020    #endregion
    5121
     
    5323
    5424    public Product FindProductById(long id) {
    55       return ExecuteWithContext<Product>((context) => {
     25      using (var context = CreateContext()) {
    5626        return context.Products.FirstOrDefault(prod => prod.ProductId == id);
    57       });
     27      }
    5828    }
    5929
     
    7242    }
    7343
    74     public void AddProduct(Product entity) {
    75       ExecuteWithContext((context) => {
    76         context.Products.Add(entity);
     44    public void InsertOrUpdateProduct(Product entity) {
     45      using (var context = CreateContext()) {
     46        throw new NotImplementedException();
     47      }
     48    }
     49
     50    void DeleteProduct(Product entity) {
     51      using (var context = CreateContext()) {
     52        throw new NotImplementedException();
     53      }
     54    }
     55
     56    #endregion
     57
     58    #region Order Methods
     59
     60    public void InsertOrUpdateOrder(Order entity) {
     61      using (var context = CreateContext()) {
     62        context.Orders.Add(entity);
     63        context.ApplyStateChanges();
    7764        context.SaveChanges();
    78       });
    79     }
    80 
    81     public void UpdateProduct(Product entity) {
    82       ExecuteWithContext((context) => {
    83         context.Products.Attach(entity);
    84         context.Entry(entity).State = System.Data.EntityState.Modified;
    85         context.SaveChanges();
    86       });
    87     }
    88 
    89     void DeleteProduct(Product entity) {
    90       ExecuteWithContext((context) => {
    91         context.Products.Remove(entity);
    92       });
    93     }
    94 
    95     #endregion
    96 
    97     #region Order Methods
    98 
    99     public void AddOrder(Order order) {
    100       ExecuteWithContext((context) => {
    101         context.Orders.Add(order);
    102         context.SaveChanges();
    103       });
     65      }
    10466    }
    10567
     
    12284
    12385    public OrderLine FindOrderLineById(long id) {
    124       return ExecuteWithContext<OrderLine>((context) => {
     86      using (var context = CreateContext()) {
    12587        return context.OrderLines.FirstOrDefault(ol => ol.OrderLineId == id);
    126       });
     88      }
    12789    }
    12890
     
    141103    }
    142104
    143     public void AddOrderLine(OrderLine entity) {
    144       ExecuteWithContext((context) => {
    145         context.OrderLines.Add(entity);
    146         context.SaveChanges();
    147       });
    148     }
    149 
    150     public void UpdateOrderLine(OrderLine entity) {
    151       ExecuteWithContext((context) => {
    152         context.OrderLines.Attach(entity);
    153         context.Entry(entity).State = System.Data.EntityState.Modified;
    154         context.SaveChanges();
    155       });
     105    public void InsertOrUpdateOrderLine(OrderLine entity) {
     106      using (var context = CreateContext()) {
     107        throw new NotImplementedException();
     108      }
    156109    }
    157110
    158111    void DeleteOrderLine(OrderLine entity) {
    159       ExecuteWithContext((context) => {
    160         context.OrderLines.Remove(entity);
    161       });
     112      using (var context = CreateContext()) {
     113        throw new NotImplementedException();
     114      }
    162115    }
    163116
     
    167120
    168121    public User FindUserById(long id) {
    169       return ExecuteWithContext<User>((context) => {
     122      using (var context = CreateContext()) {
    170123        return context.Users.FirstOrDefault(user => user.UserId == id);
    171       });
     124      }
    172125    }
    173126
     
    186139    }
    187140
    188     public void AddUser(User entity) {
    189       ExecuteWithContext((context) => {
    190         context.Users.Add(entity);
    191         context.SaveChanges();
    192       });
    193     }
    194 
    195     public void UpdateUser(User entity) {
    196       ExecuteWithContext((context) => {
    197         context.Users.Attach(entity);
    198         context.Entry(entity).State = System.Data.EntityState.Modified;
    199         context.SaveChanges();
    200       });
     141    public void InsertOrUpdateUser(User entity) {
     142      using (var context = CreateContext()) {
     143        throw new NotImplementedException();
     144      }
    201145    }
    202146
    203147    void DeleteUser(User entity) {
    204       ExecuteWithContext((context) => {
    205         context.Users.Remove(entity);
    206       });
     148      using (var context = CreateContext()) {
     149        throw new NotImplementedException();
     150      }
    207151    }
    208152
     
    212156
    213157    public UsageRecord FindUsageRecordById(long id) {
    214       return ExecuteWithContext<UsageRecord>((context) => {
     158      using (var context = CreateContext()) {
    215159        return context.UsageRecords.FirstOrDefault(prod => prod.ProductId == id);
    216       });
     160      }
    217161    }
    218162
     
    231175    }
    232176
    233     public void AddUsageRecord(UsageRecord entity) {
    234       ExecuteWithContext((context) => {
    235         context.UsageRecords.Add(entity);
     177    public void InsertOrUpdateUsageRecord(UsageRecord entity) {
     178      using (var context = CreateContext()) {
     179        throw new NotImplementedException();
     180      }
     181    }
     182
     183    void DeleteUsageRecord(UsageRecord entity) {
     184      using (var context = CreateContext()) {
     185        throw new NotImplementedException();
     186      }
     187    }
     188
     189    #endregion
     190
     191    #region Invoice Methods
     192
     193    public void InsertOrUpdateInvoice(Invoice entity) {
     194      using (var context = CreateContext()) {
     195        context.Invoices.Add(entity);
     196        context.ApplyStateChanges();
    236197        context.SaveChanges();
    237       });
    238     }
    239 
    240     public void UpdateUsageRecord(UsageRecord entity) {
    241       ExecuteWithContext((context) => {
    242         context.UsageRecords.Attach(entity);
    243         context.Entry(entity).State = System.Data.EntityState.Modified;
    244         context.SaveChanges();
    245       });
    246     }
    247 
    248     void DeleteUsageRecord(UsageRecord entity) {
    249       ExecuteWithContext((context) => {
    250         context.UsageRecords.Remove(entity);
    251       });
    252     }
    253 
    254     #endregion
    255 
    256     #region Invoice Methods
    257 
    258     public void AddInvoice(Invoice entity) {
    259       ExecuteWithContext((context) => {
    260         context.Invoices.Add(entity);
    261         context.SaveChanges();
    262       });
     198      }
    263199    }
    264200
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/HeuristicLab.Services.Optimization.Billing.csproj

    r9619 r9645  
    5959    <Compile Include="Interfaces\IGenericDao.cs" />
    6060    <Compile Include="Interfaces\IInvoiceFormattingEngine.cs" />
     61    <Compile Include="Interfaces\IObjectWithState.cs" />
    6162    <Compile Include="Interfaces\IOptimizationBilling.cs" />
    6263    <Compile Include="Business\MockupBillingService.cs" />
    6364    <Compile Include="Model\Model.cs" />
    6465    <Compile Include="Properties\AssemblyInfo.cs" />
     66    <Compile Include="Utils\DbContextUtil.cs" />
     67    <Compile Include="Utils\StateUtil.cs" />
    6568  </ItemGroup>
    6669  <ItemGroup>
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/Interfaces/IOptimizationBilling.cs

    r9619 r9645  
    2323
    2424    IList<Invoice> GetInvoices(string userName);
     25    void SaveInvoice(Invoice invoice);
    2526
    2627    User GetUser(string userName);
  • branches/OaaS/HeuristicLab.Services.Optimization.Billing/Model/Model.cs

    r9641 r9645  
    22using System;
    33using System.Collections.Generic;
     4using HeuristicLab.Services.Optimization.Billing.Interfaces;
    45namespace HeuristicLab.Services.Optimization.Billing.Model {
    56
     
    1415   */
    1516
    16   public class ContactInformation {
     17  public class ContactInformation : IObjectWithState {
    1718    public long ContactInformationId { get; set; }
    1819    public string OrganizationName { get; set; }
     
    2425    public string FirstName { get; set; }
    2526    public string Email { get; set; }
     27
     28    // Property is not mapped
     29    // It is used to track state (disconnected entities)
     30    public State EntityState { get; set; }
    2631  }
    2732
    28   public class PaymentInformation {
     33  public class PaymentInformation : IObjectWithState {
    2934    public long PaymentInformationId { get; set; }
    3035    public long UserId { get; set; }
     
    3944      set { PaymentMethodValue = (int)value; }
    4045    }
     46
     47    public State EntityState { get; set; }
    4148  }
    4249
     
    6067  }
    6168
    62   public class Product {
     69  public class Product : IObjectWithState {
    6370    public long ProductId { get; set; }
    6471    public string Name { get; set; }
     
    6673    public string ProductType { get; set; }
    6774    public double Price { get; set; }
     75
     76    public State EntityState { get; set; }
    6877  }
    6978
    70   public class User {
     79  public class User : IObjectWithState {
    7180    public long UserId { get; set; }
    7281    public long ContactInformationId { get; set; }
     
    7584    public virtual IList<PaymentInformation> PaymentInformation { get; set; }
    7685    public virtual ContactInformation ContactInformation { get; set; }
     86
     87    public State EntityState { get; set; }
    7788  }
    7889
     
    8596  }
    8697
    87   public class Order {
     98  public class Order : IObjectWithState {
    8899    public long OrderId { get; set; }
    89100    public long UserId { get; set; }
     
    112123      set { BillingPeriodValue = (int)value; }
    113124    }
     125
     126    public State EntityState { get; set; }
    114127  }
    115128
    116   public class OrderLine {
     129  public class OrderLine : IObjectWithState {
    117130    public long OrderLineId { get; set; }
    118131    public long OrderId { get; set; }
     
    123136    public virtual Order Order { get; set; }
    124137    public virtual Product Product { get; set; }
     138
     139    public State EntityState { get; set; }
    125140  }
    126141
     
    129144  }
    130145
    131   public class Invoice {
     146  public class Invoice : IObjectWithState {
    132147    public long InvoiceId { get; set; }
    133148    public long UserId { get; set; }
     
    148163      set { StatusValue = (int)value; }
    149164    }
     165
     166    public State EntityState { get; set; }
    150167  }
    151168
    152   public class InvoiceLine {
     169  public class InvoiceLine : IObjectWithState {
    153170    public long InvoiceLineId { get; set; }
    154171    public long InvoiceId { get; set; }
     
    159176    public virtual Invoice Invoice { get; set; }
    160177    public virtual Product Product { get; set; }
     178
     179    public State EntityState { get; set; }
    161180  }
    162181
    163   public class UsageRecord {
     182  public class UsageRecord : IObjectWithState {
    164183    public long UsageRecordId { get; set; }
    165184    public long UserId { get; set; }
     
    172191    public virtual User User { get; set; }
    173192    public virtual Product Product { get; set; }
     193
     194    public State EntityState { get; set; }
    174195  }
    175196}
Note: See TracChangeset for help on using the changeset viewer.