Git Product home page Git Product logo

highway.data's Introduction

Highway.Data

The fastest and smoothest way to great architecture

Documentation

We encourage you to check out our documentation site for the Highway Framework at http://hwyfwk.com, specifically the Highway.Data project site, and the Features documentation that documents how every part of Highway.Data works. Below we've reproduced our getting started section to make things easy for you, but full documentation is on the Highway.Data project site.

So you want to get started with Highway.Data, but don’t know where to start? Lets start the same place we always start with something new. "Tests!!!"

[TestClass]
public class DriversEducationServiceTests
{
   [TestMethod]
   public void ShouldAddDriverByName()
   {
		//arrange
		var context = new InMemoryDataContext();
		var service = new DriversEducationService(new Repository(context));

		//act
		service.AddDriver("Devlin");

		//assert
		context.AsQueryable<Driver>().Count(x => x.Name == "Devlin").Should().Be(1);
	}
}

Now that we have a test, lets work on an implementation. In this implementation we are going to focus on the patterns in Highway.Data. We will dive into Entity Framework, nHibernate, and RavenDb later. In order to facilitate this, we are going to use the InMemoryDataContext that ships with Highway.Data as our test stub.

We just need to add a driver to the database.

    public class DriversEducationService
    {
        private readonly IRepository _repository;

        public DriversEducationService(IRepository repository)
        {
            _repository = repository;
        }

        public void AddDriver(string name)
        {
            _repository.Context.Add(new Driver(name));
            _repository.Context.Commit();
        }
    }

    public class Driver
    {
        public string Name { get; set; }

        public Driver(string name)
        {
            Name = name;
        }
    }

Once we have the repository, we can use the Context on Repository as a unit of work. Check here and here read up on Repository or Unit of Work.

This gives us the ability to separate the persistence from the business logic of our services.

Once we have added an object we will obviously need to query the object back out. For this we will need to use a mixture of Specification Pattern and Query Object Pattern. Below is the test for querying back an object.

    [TestMethod]
    public void ShouldQueryDriversByName()
    {
        //arrange
        var context = new InMemoryDataContext();
        context.Add(new Driver("Devlin"));
        context.Add(new Driver("Tim"));
        context.Commit();

        var service = new DriversEducationService(new Repository(context));

        //act
        Driver driver = service.GetDriver("Devlin");

        //assert
        driver.Should().NotBeNull();
    }

And our service code that passes the test.

    public Driver GetDriver(string name)
    {
        return _repository.Find(new DriverByName(name));
    }

With the following query.

    public class DriverByName : Scalar<Driver>
    {
        public DriverByName(string name)
        {
            ContextQuery = c => c.AsQueryable<Driver>().Single(x => x.Name == name);
        }
    }

If we want to query a collection of entities, that is as simple as changing the base class our query object inherits from.

    public class DriversByName : Query<Driver>
    {
        public DriversByName(string name)
        {
            ContextQuery = c => c.AsQueryable<Driver>().Where(x => x.Name == name);
        }
    }

Built into the framework is the ability to fire off commands that affect the database but don't return a value. The syntax is very similar.

    public void RemoveDriversByName(string name)
    {
        _repository.Execute(new RemoveDrivers(name));
    }

    public class RemoveDrivers : Command
    {
        public RemoveDrivers(string name)
        {
            ContextQuery = c =>
            {
                foreach (var driver in c.AsQueryable<Driver>().Where(x=>x.Name == name))
                {
                    c.Remove(driver);
                }
                c.Commit();
            };
        }
    }

highway.data's People

Contributors

bmsullivan avatar chrisblock avatar coridrew avatar devlinliles avatar dliles-eprod avatar ericburcham avatar ericburcham-eprod avatar jaysmith avatar kendaleiv avatar rguptaeprod avatar secretcxman avatar trayburn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

highway.data's Issues

Create IDomain

Used to encapsulate ContextConfiguration, MappingConfiguration, ConnectionString, and an array of interceptors.

InMemoryContext needs to allow Add while Iterating

The following exception

System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
System.Collections.Generic.List`1.Enumerator.MoveNextRare()
System.Collections.Generic.List`1.Enumerator.MoveNext()
System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
System.Linq.Enumerable.d__b1`1.MoveNext()
System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
OGFlex.Areas.Admin.Controllers.CompanyUserFieldsController.Create(CompanyUserFieldModel model) in CompanyUserFieldsController.cs
OGFlex.Tests.Controllers.Admin.CompanyUserFieldsControllerTests

occurs from this code

            var allCompanyIds = _accounting.Get<Company>().Select(e => e.Id);
            foreach (var companyId in allCompanyIds)
            {
                var cufv = new CompanyUserFieldValue
                {
                    CompanyId = companyId,
                    UserField = newUF,
                    ValueBool = newUF.DefaultBool,
                    ValueDateTime = newUF.DefaultDateTime,
                    ValueDecimal = newUF.DefaultDecimal,
                    ValueString = newUF.DefaultString
                };
                _accounting.Context.Add(cufv);
            }

It should go without saying, but Company has many CompanyUserFieldValue, but this is guaranteed coming from the fact that InMemoryContext keeps one collection, and since we're iterating that list, we cannot add to that list. :(

As a developer, I'd like complete Documentation ;)

I know, I know, documentation is a chore and we all hate it.

But please, please put together full documentation with examples for every last bit of functionality this (excellent) framework provides.

I'm using the Entity Framework flavor and ran into an issue working out what the best way to update an existing object mapped from a business object would be. Nothing but tumbleweed here, an incomplete sample app (no full CRUD, nothing advanced) and a bare API definition (though that's certainly a lot better than nothing!).

Anyway, I'm really impressed so far and it looks like we'll definitely be utilizing this framework in production but the lack of full documentation is driving us nuts.

As a Developer, I want examples for each feature and it's usage

We need a example implementation on the wiki for each of the below features. Each Example Implementation should include code that demonstrates the feature, as well as explainations of the steps involve to use it.

  1. Defining mappings for Entity Framework Context
  2. Injecting mappings for Entity Framework Context
  3. Writing a query that returns a set of data
  4. Writing a query that returns a single piece of data
  5. Writing a command that doesn't return data
  6. Outputting the SQL from a Query
  7. Defining the configuration for an Aggregate Root Context
  8. Writing a Performance Test for a Query
  9. Writing a performance test for a commit
  10. Paging on a pre-written query
  11. Sorting on a pre-written query
  12. Defining Context Level Configuration
  13. IoC registration for - Unity, Windsor, StructureMap, Ninject

Execute SQL bug in v4 with EF6

For some reason this works :

{
    public class GetCountOfAllTables : AdvancedScalar<int>
    {
        public GetCountOfAllTables()
        {
            ContextQuery = c => (c as DbContext).Database.SqlQuery<int>("select count(*) from sys.tables").ToList().First();
        }
    }

But this does not:

{
    public class GetCountOfAllTables : AdvancedScalar<int>
    {
        public GetCountOfAllTables()
        {
            ContextQuery = c => c.ExecuteSqlQuery<int>("select count(*) from sys.tables").ToList().First();
        }
    }

Scalar<List<People>> vs Query<People>

I see in the documentation that it says to use Query for returning a list of objects, but I was wondering if using Scalar<List> has an down falls vs Query?

Find can't return value types

I tried to write a query to return an IEnumerable and was told it had to be a reference class, but I'm not seeing anywhere that makes that a requirement in our basic query story.

58 public IEnumerable Find(IQuery query) where T : class
59 {
60 return query.Execute(Context);
61 }

Line 58 is the offending line from Repository.cs

InMemoryContext needs to populate back references

If Blog has many Post and Post has required Blog.

// Arrange
var blog = new Blog();
var post = new Post { Blog = blog };
context.Add(post);

// Act
var fetchedBlog = context.AsQueryable<Blog>().First();

// Assert
fetchedBlog.Posts.Count().Should().Be(1);

Error Message when Initializing Ioc

I am building a WPF application using the MVVM Light framework. When I try and register the IDataContext interface I am running into this error: The target context 'Highway.Data.DataContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

I am trying to initialize the DataContext like so:

var context = new DataContext(connectionString, new ElverMappings());
SimpleIoc.Default.Register(() => { return context; });

However if a make a call to the database like the following, I don't get the error.

var repository = new Repository(context);
repository.Context.AsQueryable().Any();

Right after I initialize the IDataContext, I also initialize the IMappingConfiguration, ILog, and IContextConfiguration.

Am I missing something?

As a Developer I Want to be able to genererate a Query Report So that I can optimize them for performance

HD Query Dumper

A class that would allow for all query specifications in an application to be dumped to a text file with ease. The challenge is in providing default values for value types that are passed to the query specification. A bit of reflection magic could be used to find all paramaters to the constructor, inspect their type and then provide some default values based on type. It would also need to be robust enough that if a complex type is being passed, to add default values for all properties, and if any dependencies are detected to instantiate them and provide default values for them as well. It would need to hydrate the complete object graph.

The idea is that by providing default values the query can be easily produced. Granted that putting "Hello" or some other nonsense in for strings does not create a query that will actually return data from the system. But it does allow for an easy mechinism to get a query stub generated from the code and into a file or files. Once this is done, it is pretty easy to edit the sql queries to make them actually return data.

If there is a way to setup meta data that would know how to populate value types and complex objects that would be awesome as well. An idea was to use some kind of mocking to proide that. But this didn't feel like a v 1.0 feature.

Example Usage:

Dump all queries to a single file

var queryDumperConfig = new QueryDumperConfiguration();

queryDumperConfig.WriteToSingleFile = true;
queryDumperConfig.FileName = "MyQueries.txt";
queryDumperConfig.Path = "C:\Temp";

var dumper = new QueryDumper(queryDumperConfig);
dumper.Dump();

Dump all queries to seperate files

var queryDumperConfig = new QueryDumperConfiguration();

queryDumperConfig.WriteToSingleFile = false;
queryDumperConfig.Path = "C:\Temp";

var dumper = new QueryDumper(queryDumperConfig);
dumper.Dump();

Create AllAssembliesMappingConfiguration

This should add all mappings from all referenced assemblies. It should also be the default for mappings if you're using the new DataContext(connString) constructor.

AddOrUpdate() with Highway.Data

Is there a way to access the .AddOrUpdate(x => x.Name, entities.ToArray()) method for entity framework using Highway.Data?

If not, is there a work around? I have a local database and the AddOrUpdate() makes it very easy to keep the database synced.

Create Mappings.FromAssemblyContaining<T> for fluent mappings

Allow simple mappings to be handled via an API like:

Component.For<IMappingConfiguration>()
    .Instance(Mappings.FromAssemblyContaing<Foo>())

This should be fluently continuable ala:

Component.For<IMappingConfiguration>()
    .Instance(Mappings.FromAssemblyContaing<Foo>()
    .AndFromAssemblyContaining<Bar>().
    .AndFromAssemblyContaining<Baz>())

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.