I have an application using the Repository pattern to abstract how data is retrieved. I plan on using a web service for retrieving the data, but during development will just mock it out. However, I am stuck on how to get a find method working. I have the following so far, but I am not sure that query.Compile() is the right thing to be doing (no examples I have found do that). I get a compiler error saying there is no overload for Linq's Where method that takes a System.Linq.Expressions.Expression. Here is where I am at so far:
public async Task<IEnumerable<Customer>> FindAsync(Expression<Func<Customer, bool>> query)
{
var allCustomers = await GetAllAsync(true);
return allCustomers.Where(query.Compile());
}
At some point, I would like to figure out how to avoid retrieving all customers and then applying the expression also, but am not sure how I can pass the expression to a REST webservice so the filtering can happen at the data access layer.
The implementations of Repository pattern I've seen generally look like this (using Entity Framework):
public class Repository<T> where T : class
{
private readonly DbSet<T> _queryableBase;
public Repository(DbSet<T> queryableBase)
{
_queryableBase = queryableBase;
}
public T Select(IFilter<T> filterClass)
{
return filterClass.Filter(_queryableBase.AsQueryable()).First();
}
public IEnumerable<T> SelectMany(IFilter<T> filterClass)
{
return filterClass.Filter(_queryableBase.AsQueryable());
}
public void Delete(T item)
{
_queryableBase.Remove(item);
}
public void Add(T item)
{
_queryableBase.Add(item);
}
}
Then the filter object:
public interface IFilter<T>
{
IEnumerable<T> Filter(IEnumerable<T> queryableBase);
}
Example filtering implementation:
class FilterChris : IFilter<ATestObject>
{
public IEnumerable<ATestObject> Filter(IEnumerable<ATestObject> queryableBase)
{
return queryableBase.Where(o => o.FirstName == "Chris");
}
}
public class ATestObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Note that filters can chain.
At some point, I would like to figure out how to avoid retrieving all
customers and then applying the expression also, but am not sure how I
can pass the expression to a REST webservice so the filtering can
happen at the data access layer.
Assuming your client app is written in C# you could use breeze-sharp:
http://www.breezejs.com/breeze-sharp-documentation/query-examples#whereSimple
BreezeSharp communicates with any service that speaks HTTP and JSON.
Are you serving data with Web API, OData or MVC backed by Entity
Framework in front of SQL Server? Breeze has a great out-of-the-box
story.
BreezeSharp would allow you to write code like this on the client:
var query3 = query1.Where(td => !td.IsArchived && !td.IsDone);
var activeTodos = awaitManager.ExecuteQuery(query3);
Related
I am very new to C# and ServiceStack and I am working on a small project that consists on calling a third party API and loading the data I get back from the API into a relational database via ServiceStack's ORMLite.
The idea is to have each endpoint of the API have a reusable model that determines how it should be received in the API's response, and how it should be inserted into the database.
So I have something like the following:
[Route("/api/{ApiEndpoint}", "POST")]
public class ApiRequest : IReturn<ApiResponse>
{
public Int32 OrderId { get; set; }
public DateTime PurchaseDate { get; set; }
public String ApiEndpoint { get; set; }
}
public class ApiResponse
{
public Endpoint1[] Data { get; set; }
public String ErrorCode { get; set; }
public Int32 ErrorNumber { get; set; }
public String ErrorDesc { get; set; }
}
public class Endpoint1
{
[AutoIncrement]
public Int32 Id { get; set; }
[CustomField("DATETIME2(7)")]
public String PurchaseDate { get; set; }
[CustomField("NVARCHAR(50)")]
public String Customer { get; set; }
[CustomField("NVARCHAR(20)")]
public String PhoneNumber { get; set; }
public Int32 Amount { get; set; }
}
My first class represents the API's request with its route, the second class represents the API's response. The API's response is the same for all endpoints, but the only thing that varies is the structure of the Data field that comes back from that endpoint. I've defined the structure of one of my endpoints in my Endpoint1 class, and I am using it in my API's response class. As you can see, I am also defining a few attributes on my Endpoint1 class to help the ORM make better decisions later when inserting the data.
Ok, so the issue is that I have about 15 endpoints and I don't want to create 15 ApiResponse classes when I know the only thing that changes is that first Data field in the class.
So I made something like this:
public class DataModels
{
public Type getModel(String endpoint)
{
Dictionary<String, Type> models = new Dictionary<String, Type>();
models.Add("Endpoint1", typeof(Endpoint1));
// models.Add("Endpoint2", typeof(Endpoint2));
// models.Add("Endpoint3", typeof(Endpoint3));
// and so forth...
return models[endpoint];
}
}
I would like for getModel() to be called when the request is made so that I can pass in the ApiEndpoint field in the ApiRequest class and store the type that I want my Data field to have so that I can dynamically change it in my ApiResponse class.
In addition, there is the ORM part where I iterate over every endpoint and create a different table using the model/type of each endpoint. Something like this:
endpoints.ForEach(
(endpoint) =>
{
db.CreateTableIfNotExists<Endpoint1>();
// inserting data, doing other work etc
}
);
But again, I'd like to be able to call getModel() in here and with that define the model of the specific endpoint I am iterating on.
I've attempted calling getModel() on both places but I always get errors back like cannot use variable as a typeand others... so I am definitely doing something wrong.
Feel free to suggest a different approach to getModel(). This is just what I came up with but I might be ignoring a much simpler approach.
When I DID understand you correctly, you have different API-Calls which all return the same object. The only difference is, that the field "Data" can have different types.
Then you can simply change the type of data to object:
public object Data { get; set; }
And later simply cast this to the required object:
var data1=(Endpoint1[]) response.Data;
You're going to have a very tough time trying to dynamically create .NET types dynamically which requires advanced usage of Reflection.Emit. It's self-defeating trying to dynamically create Request DTOs with ServiceStack since the client and metadata services needs the concrete Types to be able to call the Service with a Typed API.
I can't really follow your example but my initial approach would be whether you can use a single Service (i.e. instead of trying to dynamically create multiple of them). Likewise with OrmLite if the Schema of the POCOs is the same, it sounds like you would be able to flatten your DataModel and use a single database table.
AutoQuery is an example of a feature which dynamically creates Service Implementations from just a concrete Request DTO, which is effectively the minimum Type you need.
So whilst it's highly recommended to have explict DTOs for each Service you can use inheritance to reuse the common properties, e.g:
[Route("/api/{ApiEndpoint}/1", "POST")]
public ApiRequest1 : ApiRequestBase<Endpoint1> {}
[Route("/api/{ApiEndpoint}/2", "POST")]
public ApiRequest2 : ApiRequestBase<Endpoint1> {}
public abstract class ApiRequestBase<T> : IReturn<ApiResponse<T>>
{
public int OrderId { get; set; }
public DateTime PurchaseDate { get; set; }
public string ApiEndpoint { get; set; }
}
And your Services can return the same generic Response DTO:
public class ApiResponse<T>
{
public T[] Data { get; set; }
public String ErrorCode { get; set; }
public Int32 ErrorNumber { get; set; }
public String ErrorDesc { get; set; }
}
I can't really understand the purpose of what you're trying to do so the API design is going to need modifications to suit your use-case.
You're going to have similar issues with OrmLite which is a Typed code-first POCO ORM where you're going to run into friction trying to use dynamic types which don't exist at Runtime where you'll likely have an easier time executing Dynamic SQL since it's far easier to generate a string than a .NET Type.
With that said GenericTableExpressions.cs shows an example of changing the Table Name that OrmLite saves a POCO to at runtime:
const string tableName = "Entity1";
using (var db = OpenDbConnection())
{
db.DropAndCreateTable<GenericEntity>(tableName);
db.Insert(tableName, new GenericEntity { Id = 1, ColumnA = "A" });
var rows = db.Select(tableName, db.From<GenericEntity>()
.Where(x => x.ColumnA == "A"));
Assert.That(rows.Count, Is.EqualTo(1));
db.Update(tableName, new GenericEntity { ColumnA = "B" },
where: q => q.ColumnA == "A");
rows = db.Select(tableName, db.From<GenericEntity>()
.Where(x => x.ColumnA == "B"));
Assert.That(rows.Count, Is.EqualTo(1));
}
Which uses these extension methods:
public static class GenericTableExtensions
{
static object ExecWithAlias<T>(string table, Func<object> fn)
{
var modelDef = typeof(T).GetModelMetadata();
lock (modelDef)
{
var hold = modelDef.Alias;
try
{
modelDef.Alias = table;
return fn();
}
finally
{
modelDef.Alias = hold;
}
}
}
public static void DropAndCreateTable<T>(this IDbConnection db, string table)
{
ExecWithAlias<T>(table, () => {
db.DropAndCreateTable<T>();
return null;
});
}
public static long Insert<T>(this IDbConnection db, string table, T obj, bool selectIdentity = false)
{
return (long)ExecWithAlias<T>(table, () => db.Insert(obj, selectIdentity));
}
public static List<T> Select<T>(this IDbConnection db, string table, SqlExpression<T> expression)
{
return (List<T>)ExecWithAlias<T>(table, () => db.Select(expression));
}
public static int Update<T>(this IDbConnection db, string table, T item, Expression<Func<T, bool>> where)
{
return (int)ExecWithAlias<T>(table, () => db.Update(item, where));
}
}
But it's not an approach I'd take personally, if I absolutely needed (and I'm struggling to think of a valid use-case outside of table-based Multitenancy or sharding) to save the same schema in multiple tables I'd just be using inheritance again, e.g:
public class Table1 : TableBase {}
public class Table2 : TableBase {}
public class Table3 : TableBase {}
May be this is a stupid question.
I have some model class in a Asp.Net web api 2.2 application, which implements an interface ICountryOfOrigin.
I need to filter records by applying where clause as shown below. I have to repeat this logic in many controllers with different models which implement ICountryOfOrigin.
Is it possible to move the filtering logic into a separate method and apply it to the controller action through data annotation?
My intention is to eliminate the repeating code.
Is it possible?
//Interface
public Interface ICountryOfOrigin
{
string Country {get;set;}
}
//Model
public class Product : ICountryOfOrigin
{
..
string Country {get;set;}
}
//Action
public IHttpActionResult Get()
{
List<string> euCountries = GetEuCountries();
Product product = _repository.Products.GetAll().Where(p=> euCountries.Contains(p.countries); // The filter is applied here
return Ok(products);
}
//Need to achieve something like this
[EuCountriesOnly]
public IHttpActionResult Get()
{
List<string> euCountries = GetEuCountries();
Product product = _repository.Products.GetAll();
return Ok(products);
}
Any experts help me on this?
I guess I would shoot anybody who would implemented it the way you want. Believe me, it's not cool at all to alter behavior of some method you're calling with an attribute you put on a calling method.
Just put the logic into an extension method on your repository type and call it a day:
public static class RepoExtensions
{
private static readonly euCountries = new Country[]{};
public static IEnumerable<ICountryOfOrigin> GetEU(this Repository repo)
{
return repo.Products.GetAll().Where(p=> euCountries.Contains(p.countries);
}
}
I'm assuming that your repository is of type Repository, you'll need to put the real type instead of it.
Abstract view: I want to pass information from one layer to another (note: when there's a better title for this thread let me know).
I have a ViewModel which communications with my Views and my Service layer.
And I have a Service layer communication with my persistence layer.
Let's assume I have the following classes:
public class EmployeeViewModel()
{
// The following properties are binded to my View (bidirectional communication)
public Firstname ...
public Lastname ...
public Email ...
public void PerformingSearch()
{
...
EmployeeService.Search(...);
...
}
}
public class EmployeeService()
{
public List<Employee> Search(...)
{
// Searching in db
}
}
What is best practice to hand over the data from my ViewModel to my Service layer (e. g. for performing a search)?
I see a few options (ViewModel perspective):
EmployeeService.Search(Firstname, Lastname, Email);
EmployeeService.Search(employeeSearchModel); // In this case I would need another model. How should the model be instantiated?
EmployeeService.Search(this); // Convertion has to be done somewhere
Is there any design pattern for this problem? How is it called? What option is best? Did I miss anything?
Describing your problem space
Your particular example tells me that your current architecture contains a service layer that sort of acts as a proxy to your data access layer. Without more in-depth knowledge of your architecture I would suggest a possible solution to keep it simple as much as your environment allows.
Now let's try to pick a strategy to get a possible solution model.
Your user story sounds like: "a user submits information to obtain a list of employees".
Your current use-case simplified:
UI: submits some information that you need to serve;
VM: receives the search terms and passes it next to the service layer;
SL: sends the received data to Data Access Layer (and maybe updates the response values to VM properties);
DAL: looks up information in persistence store and returns the obtained values.
A refactored use-case example:
VM: invokes a query with the needed values encapsulated and set the properties to display in the UI.
Looks easier right?
Enter: Command Query Separation
In short CQS:
States that every method should either be a command that performs
an action, or a query that returns data to the caller, but not both.
In your particular case we need to focus on queries, where:
Queries: Return a result and do not change the observable state of the system (are free of side effects).
But how does this help you? Let's see.
A very good and detailed explanation of CQS query-side can be read fully at the "Meanwhile... on the query side of my architecture" blog post from Steven.
Query concept applied to your problem
Defining an interface for the query object
public interface IQuery<TResult> {}
The query handler definition:
public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
Now here is an implementation of your "search" query object. This is effectively the answer for your "how to pass information" question :
public class FindEmployeeBySearchTextQuery : IQuery<Employee>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
And last a query handler that you will pass in your query object:
public class FindEmployeeBySearchTextQueryHandler
: IQueryHandler<FindEmployeeBySearchTextQuery, List<Employee>>
{
private readonly IDbContext db;
public FindEmployeeBySearchTextQueryHandler(IDbContext db)
{
this.db = db;
}
public List<Employee> Handle(FindEmployeeBySearchTextQuery query)
{
return (
from employee in this.db.employees
where employee.FirstName.Contains(query.FirstName) ||
employee.LastName.Contains(query.LastName) ||
employee.Email == query.Email
select employee )
.ToList();
}
}
Note: this Handle() example implementation uses Entity Frameworks' IDbContext, you have got to rework/modify this according to your needs (ADO.NET, NHibernate, etc.).
And finally in your view model:
public class EmployeeViewModel()
{
private readonly IQueryHandler _queryHandler;
public EmployeeViewModel(IQueryHandler queryHandler)
{
_queryHandler = queryHandler;
}
public void PerformingSearch()
{
var query = new FindEmployeeBySearchTextQuery
{
FirstName = "John",
LastName = "Doe",
Email = "stack#has.been.over.flowed.com"
};
List<Employee> employees = _queryHandler.Handle(query);
// .. Do further processing of the obtained data
}
}
This example assumes that you are using Dependency Injection.
You get IQueryHandler implementation injected into your view models constructor and later work with the received implementation.
Using this approach your code becomes cleaner, more use-case driven and will have better isolation of responsibilities which you can easily test and decorate with further cross-cutting concerns.
Good afternoon fellow stackers (or overflowers, whichever you prefer), this is more of a cleanliness and convenience issue than anything else but I can't imagine that I'm the only one who's ever wondered about it so here we go...
I've got a basic OData enabled WCF Data Service class that's using my Entity Framework data context.
[JsonpSupportBehavior]
public class ControlBindingService : DataService<MyDataContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.DataServiceBehavior.AcceptCountRequests = true;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}
protected override MyDataContext CreateDataSource()
{
if (HttpContext.Current == null)
throw new InvalidOperationException("The WCF Data Services implementation must be hosted in IIS.");
string username;
if (HttpContext.Current.User.Identity.IsAuthenticated)
username = HttpContext.Current.User.Identity.Name;
else
{
// The request didn't have user identity, attempt to find UserName in the
// request header before returning 401 to the caller.
if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["UserName"]))
{
username = HttpContext.Current.Request.Headers["UserName"];
// REVIEW: We should validate user before passing it to the datacontext.
}
else
throw new DataServiceException(401, "Client did not pass required authentication information.");
}
return MyDataContext.GetInstance(username);
}
[WebGet]
public List<DailyKeyPerformanceIndicator> GetResourceKPIs(
int resourceId, string jsonStart, string jsonEnd, int scenarioId)
{
DateTime start = jsonStart.DeserializeJson<DateTime>();
DateTime end = jsonEnd.DeserializeJson<DateTime>();
if (scenarioId < 1)
{
scenarioId = CurrentDataSource.GetScenarios()
.Single(s => s.IsProduction).ScenarioID;
}
return CurrentDataSource.GetDailyResourceKPI(
scenarioId, start, end, resourceId);
}
}
The data context is just a standard (code-first) DbContext implementation with properties exposing the entity sets, etc..
However, we also have methods on there to expose some tables that we wanted to enforce some constraints upon. Specifically (see code below), we want to know what the caller wants to use the data for so we can return only the appropriate results. For example, if the caller wants to get rows from the employees table--they may want to get all rows, or only rows that they have update privileges for.
[Serializable]
public partial class MyDataContext : DbContext
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext()
: base("name=MyDBString")
{ }
// Standard table properties...
public DbSet<User> Users
{
get { return this.Set<User>(); }
}
public DbSet<UserSetting> UserSettings
{
get { return this.Set<UserSetting>(); }
}
public DbSet<SettingDefinition> SettingDefinitions
{
get { return this.Set<SettingDefinition>(); }
}
// Restricted table methods...
public DbSet<Client> GetClients(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<Client>(perms);
}
public DbSet<Employee> GetEmployees(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<Employee>(perms);
}
}
Now to the root of the issue... What I'd like to avoid having to do is writing a [WebGet] for each and every "restricted table method" on my data context. The reason is really nothing more than redundancy--the [WebGet] method would end up being a direct pass-through to the data context.
So in summary, I'd say what I'm basically looking to do is to mark methods from my data context class that WCF will expose in the same way it does for my DbSet properties. Any takers?
Thanks! J
This is an interesting problem. I'm trying to do similar things. This is kind of throwing a dart here but have you tried something like this? You should probably separate the generics out so you don't create a unique context with each type, but it seems like you should be able to get rid of the duplicate code with generics.
[Serializable]
public partial class MyDataContext<T> : DbContext where T : class
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext()
: base("name=MyDBString")
{ }
// Standard table properties...
public DbSet<T> SettingDefinitions
{
get { return this.Set<T>(); }
}
// Restricted table methods...
public DbSet<T> GetClients(
DatabasePermissions perms = DatabasePermissions.Select)
{
// getPermissibleSet is a method in a helper class that does some
// magical querying and produces a filtered DbSet.
return getPermissibleSet<T>(perms);
}
}
Before there was "web api", one had to do actions of the type JsonResult GetPersons(..). Now, with web api, one can have List<Person> GetPersons(..).
I thought the whole point of this was to reutilize the actions, that is: call GetPersons from another action (maybe ActionResult GetPersons(..)).
But after many serialization problems I'm figuring out that this is not an option. For example, as simple as if the object has an enum inside, it can't be serializated to json.
So I ended up with many dynamic X(...) returning anonymous types and I cant really reuse many things of my API. Anny suggestions?
A example of a repeated code is the following:
Json:
from a in b select new { ... }
Not json
from a in b
Also, I've read in many forums that is not good to return the EF object itself, and thats exactly what web api motivates (and the existence of [ScriptIgnore])
The question: How do I reuse queries in the API and in the normal controllers?
How do I reuse queries in the API and in the normal controllers?
By not defining the queries in your API or MVC controllers. You can define the queries in a shared assembly, external to the MVC project, and have the controllers call into that layer.
Example:
Externalized
public interface IQuery<TResult> {}
public interface IQueryProcessor
{
TResult Execute<TResult>(IQuery<TResult> query)
}
public class MyQueryObject : IQuery<MyEntity[]>
{
public string QueryParam1 { get; set; }
public int QueryParam2 { get; set; }
}
API Controller
public class MyApiController : ApiController
{
private readonly IQueryProcessor _queryProcessor;
public MyApiController(IQueryProcessor queryProcessor)
{
_queryProcessor = queryProcessor
}
public IEnumerable<MyApiModel> Get
([FromUri] string queryParam1, int queryParam2)
{
var query = new MyQueryObject
{
QueryParam1 = queryParam1,
QueryParam2 = queryParam2,
};
var results = _queryProcessor.Execute(query);
return Mapper.Map<IEnumerable<MyApiModel>>(results);
}
}
MVC Controller
public class MyMvcController : Controller
{
private readonly IQueryProcessor _queryProcessor;
public MyMvcController(IQueryProcessor queryProcessor)
{
_queryProcessor = queryProcessor
}
public ViewResult Index(string queryParam1, int queryParam2)
{
var query = new MyQueryObject
{
QueryParam1 = queryParam1,
QueryParam2 = queryParam2,
};
var results = _queryProcessor.Execute(query);
var models = Mapper.Map<IEnumerable<MyViewModel>>(results);
return View(models);
}
}