Tag: Entity Framework

  • Entity Framework: StoreGeneratedPattern="Computed"

    Entity Framework: StoreGeneratedPattern="Computed"

    We recently had a problem where our fields with default values where not getting properly populated in the database during row creation. This can occur when the EDMX model is created in the designer and the default fields do not have their StoreGeneratedPattern property set to Computed or Identity.

    Easy enough to fix, simply open the model in the VS designer, select the field, open the properties view and make the required changes.

    However we have also seen a problem where these fields are still not getting set correctly even after this change has been applied. Looking into the EDMX model within an XML view we can see that in some cases the StoreGeneratedPattern=Computed property has been retained on the Entity, but removed from the EntitySet, for example:

    Entity: Product

    <entitytype name="Product">
    <key>
    <propertyref name="ProductId" />
    </key>
    <property name="ProductId" type="Int32" nullable="false"></property>
    <property name="ProductDescription" type="String" maxlength="30" fixedlength="false" unicode="false"></property>
    <property name="ProductType" type="String" maxlength="1" fixedlength="true" unicode="false"></property>
    <property name="EntityRowID" type="Guid" nullable="false" annotation:storegeneratedpattern="Computed"></property>
    <property name="EntityLastUpdated" type="DateTime" nullable="false" annotation:storegeneratedpattern="Computed"></property>
    <property name="EntityIsDeleted" type="Boolean" nullable="false" annotation:storegeneratedpattern="Computed"></property>
    </entitytype>
    

    EntitySet: Products

    The StoreGeneratedPattern has gone missing 😦

    <entitytype name="Products">
    <key>
    <propertyref name="ProductId" />
    </key>
    <property name="ProductId" nullable="false" type="Int32"></property>
    <property name="ProductDescription" type="String" unicode="false" fixedlength="false" maxlength="30"></property>
    <property name="ProductType" type="String" unicode="false" fixedlength="true" maxlength="1"></property>
    <property name="EntityRowID" nullable="false" type="Guid"></property>
    <property name="EntityLastUpdated" nullable="false" type="DateTime"></property>
    <property name="EntityIsDeleted" nullable="false" type="Boolean"></property>
    </entitytype>
    

    This has occurred on a lot of tables, and we don’t know how or why that has crept in. To fix this we have had to manually fix up the XML file for the EntitySets effected:

    <entitytype name="Products">
    <key>
    <propertyref name="ProductId" />
    </key>
    <property name="ProductId" nullable="false" type="Int32"></property>
    <property name="ProductDescription" type="String" unicode="false" fixedlength="false" maxlength="30"></property>
    <property name="ProductType" type="String" unicode="false" fixedlength="true" maxlength="1"></property>
    <property name="EntityRowID" nullable="false" type="Guid" storegeneratedpattern="Computed"></property>
    <property name="EntityLastUpdated" nullable="false" type="DateTime" storegeneratedpattern="Computed"></property>
    <property name="EntityIsDeleted" nullable="false" type="Boolean" storegeneratedpattern="Computed"></property>
    </entitytype>
    
  • Real World: Unit Testing Queries Against Entity Framework (EF) Model / Repositories

    Real World: Unit Testing Queries Against Entity Framework (EF) Model / Repositories

    Unit testing is a tricky beast. As with all unit tests it is important to abstract any dependencies – so in the case of EF it’s the data persistence source. This must be handled carefully because EF creates a container that performs the interaction with the data source. Abstracting that container (via mocking or stubbing) is painfully hard.

    There are a few approaches for doing this, this is mine. I’m using the following tooling:

    The pattern uses the following DAL class structure (like a pseudo-repository pattern against an example Product database table):

    • ProductDataRepository: IProductDataRepository – A thin layer to EF, returns only IQueryable<T> types from raw EF lookups. No filters, sorting or other queries are applied here as this class is not unit testable. This class internal to the DAL assembly.
    • ProductRepository(IProductDataRepository repos) – Constructor takes an instance of the IProductDataRepository interface, and uses this for executing specific queries against the base IQueryable<T> values. This class is exposed for external calls. This is unit-tested.

    The unit tests can use Moles to stub an instance of IProductDataRepository (delegating the internal Get… methods to returning a hard coded collection of test data) that is then passed to the instance of ProductRepository under test.

    Looking at these classes from the bottom up, as an example:

    ProductDataRepository

    To Provide a thin layer that only returns IQueryable<T> (our example also filters out deleted rows):

    public class ProductDataRepository : IProductDataRepository {
    
    private MyDatabase_ModelContainer _model;
    protected internal MyDatabase_ModelContainer Model {
    get {
    if (_model == null) {
    _model = new MyDatabase_ModelContainer();
    }
    return _model;
    }
    }
    
    public IQueryable<product> GetProducts() {
    return Model.Products.Where(p => p.IsTombstoned == false);
    }
    }
    

    ProductRepository

    Core Requirement: Provide the implementation and execution of the data lookup. Consumes an instance of IProductDataRepository via constructor injection.

    public class ProductRepository{
    public ProductRepository() : this(new ProductDataRepository()) {
    }
    
    private IProductDataRepository _mRepository;
    public ProductRepository (IProductDataRepository iRepository) {
    _mRepository = iRepository;
    }
    
    public Product GetProduct(String productKey) {
    return mRepository.GetProducts().FirstOrDefault(p => p.ProductKey.Contains(productKey));
    }
    
    public List<Product> GetProducts (String productKey) {
    return mRepository.GetProducts().Where(p => p.ProductKey.Contains(productKey).ToList();
    }
    }
    

    So, we can see that this is making calls to:

    mRepository.GetProducts()

    Which returns an IQueryable<T> type, then implements required functionality:

    .Where(p => p.ProductKey.Contains(productKey))

    and then executes the Query:

    .ToList();

    GetProductsTest

    To test the ProductRepository we can create an instance and stub the IProductDataRepository. The mocking and standard setup is done in an abstract class, to provide reusability for other tests that may require this functionality:

        [TestClass]
    public abstract class ProductTestContext
    {
    private IProductDataRepository _dataRepository;
    private IProductDataRepository DataRepository
    {
    get {
    if (_dataRepository == null) {
    _dataRepository = new SIProductDataRepository() {
    GetProducts = () => Products.AsQueryable()
    };
    }
    return _dataRepository;
    }
    }
    
    private ProductRepository _ProductRepository;
    public ProductRepository ProductRepository
    {
    get {
    if (_ProductRepository == null) {
    _ProductRepository = new ProductRepository(DataRepository);
    }
    return _ProductRepository;
    }
    }
    
    private List<Product> _products;
    public List<Product> Products
    {
    get {
    if (_products == null) {
    _products = new List<Product>();
    
    for (int i = 1; i <= 9; i++) {
    _products.Add(new Product(){ ProductKey = "MyKey" + i });
    }
    }
    return _products;
    }
    }
    
    }
    

    So, here we can see the IProductDataRepository readonly property returns a stubbed instance new new SIProductDataRepository. This stub is generated by the Moles framework (see Moles documentation on how to do this). During the creation of this object we delegate the GetVouchers method to return the concrete (and hardcoded because this is a unit test) instance of Products.AsQueryable():

    GetProducts = () => Products.AsQueryable()

    The .AsQueryable() is essential to insure the instance of IProductDataRepository, that is used during the test, returns the same type as the instance used in the real world.

    Now our unit test class can inherit ProductTestContext and Arrange, Act and Assert the required tests easily:

        [TestClass]
    public class GetProductsTest : ProductTestContext
    {
    
    [TestMethod]
    public void GetSingleProduct()
    {
    // repeat the test for each instance in the test collection
    for (int i = 1; i <= 9; i++) {
    // Arrange – most of the Arrangement is done in the abstract
    var goodProductKey = "MyKey" + i;
    
    // Act – on the abstract instance of ProductRepository,
    //            which is using the stubbed instance of ProductDataRepository
    var product = ProductRepository.GetProduct(goodProductKey);
    
    // Assert – make sure the correct product is returned from the stubbed data
    Assert.IsNotNull(product);
    Assert.IsTrue(product.ProductKey.Equals(goodProductKey));
    }
    }
    
    [TestMethod]
    public void GetIndivudalFilteredProducts()
    {
    // repeat the test for each instance in the test collection
    for (int i = 1; i <= 9; i++) {
    // Arrange – most of the Arrangement is done in the abstract
    var goodProductKey = "MyKey" + i;
    
    // Act – on the abstract instance of ProductRepository,
    //            which is using the stubbed instance of ProductDataRepository
    var products = ProductRepository.GetProducts(goodProductKey);
    
    // Assert – make sure the correct products are returned from the stubbed data
    Assert.IsNotNull(products);
    Assert.IsTrue(products.Count == 1);
    }
    }
    
    [TestMethod]
    public void GetMultipleFilteredProducts()
    {
    // Expectation – all the results in the abstract Products collection should be returned
    var expectation = Products.Count;
    
    // Arrange – most of the Arrangement is done in the abstract
    var goodProductKey = "MyKey";
    
    // Act – on the abstract instance of ProductRepository,
    //            which is using the stubbed instance of ProductDataRepository
    var products = ProductRepository.GetProducts(goodProductKey);
    
    // Assert – make sure the correct products are returned from the stubbed data
    Assert.IsNotNull(products);
    Assert.AreEqual(expectation, products.Count);
    }
    }
    
  • Silverlight 3, Validation, MVVM, WCF and EF

    All the current articles and tutorials on Silverlight 3 Validation show really simplistic examples, business objects in the UI space, no services etc etc

    My Problem

    When the business objects are being created and managed via the entity framework, there does not appear to be any simple ways of adding the validation properties to the object fields. This means that by the time the object gets to the UI, we have no control.

    in addition to this I need to be able to provide UI base validation and messaging based on user inputs. This has to happen on the field edit and also on β€œSave click”. Not as easy as it sounds.

    MY Workaround

    Anyway, I have a workaround that appears to be doing what I need. This involves a few more tweaks than I feel is appropriate, so I’d be interested to hear your thoughts on this approach. Anyway, our form is as follows:

    Previously we had a business object in the ViewModel (FocusedDepartment) and were binding the values of the textboxes to the fields of this object, for example:

    <TextBox x:Name="Txt_Number" Text="{Binding Mode=TwoWay, Path=FocusedDepartment.DepartmentId}" />

    The problem with this was the FocusedDepartment type (Department) was derived from the service layer, which in turn had come from our EF model. We did not find a solution to attach the validation properties to the EF model objects. The workaround for this was to add specific properties into the ViewModel to support the fields, and attach validation properties to these:

    This property still uses the FocusedDepartment property as a backing store. In the xaml we changed our binding to use this new property:

    <TextBox x:Name="Txt_Number" Text="{Binding Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True, Path=DepartmentId}" />

    The FocusedDepartment property also had to notify property changes for the new fields:

    //the currently selected item, bound to the datacontext of the view
    private Department _focusedDepartment = new Department();
    public Department FocusedDepartment
    {
    get { return _focusedDepartment; }
    set
    {
    _focusedDepartment = value;
    _OnPropertyChanged("FocusedDepartment");


    _OnPropertyChanged("Description");
    _OnPropertyChanged("DepartmentId");
    }
    }

    From this point we where able to see the validation on the text boxes appear correctly but only when the values in the textboxes had been changed.

    When tabbing through the fields, the bound fields where not getting touched, so the validation was not occurring. To workaround this issue I have added some code to the Save button click event (sorry MVVM purists!!) to update the source of the binding expressions, then checked the error count against the ViewModel before submitting the save action:

    Firstly, I have a handler to manage the error count in the VM

    Then handled the save button click in code behind

    This ensures the fields are valid (and the validation messages are displayed) before committing the Save action to the service.

    This approach (particularly the checking and setting of values directly in the VM) feels pretty dirty at the moment L, but it does seem to work for UI validation.