I am trying to use OData v4 from the Webstack nightly builds for my web service. During the creation of the EDM model in an attempt to create the navigation properties I am instantiating the EdmNavigationPropertyInfo object. I am not sure what needs to be set on the DependentProperties and the PrincipalProperties.
Appreciate any help in pointing me to helpful documentation on using the odata v4 api's.
Do you have clr types correspond to these EDM types? if yes, just try below code.
Assume the CLR types are:
public class Customer
{
public int Id{get;set;}
public string Name{get;set;}
public IList<Order> Orders{get;set;}
}
public class Order
{
public int Id{get;set;}
public String Description{get;set;}
}
Then to get the Edm Model, you could use below code:
public static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customers");
builder.EntitySet<Order>("Orders");
builder.Namespace = typeof(Customer).Namespace;
var edmModel = builder.GetEdmModel();
return edmModel;
}
The Orders will automatically become a navigation property of the Edm Customer type.
These samples may help you:https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/
Related
I am trying to use ASPNET Core's new ODATA feature to expose data from my application. All of my data access is exposed through a set of common base classes so instead of creating 50 different ODataController classes, I'd like to have one common class and just instantiate it with different type parameters. I have my common class created but I am at a loss as to how to tell ASPNETCORE to create a bunch of controllers using reflection.
Does anyone have any examples of how to do this? I basically want to be able to write code like:
ODataControllers.Add(new CommonApiController<MatterJson, IMatterCommand, MatterStorage, MatterApi>());
(Of course I'll automate that via reflection as well, I just want to give that as an example).
I have my controller class as follows:
public class CommonApiController<TJson, TAdd1, TStorage, TApi> : ODataController
where TJson : class, IDResult, ITimestamped, new()
where TAdd1 : class, IApiCommand
where TStorage : RepositoryItem<TJson, TStorage>, new()
where TApi : CrudApi<TJson, TAdd1> {
public ICachedCrudApi<TJson, TAdd1, TStorage, TApi> API { get; private set; }
public CommonApiController(ICachedCrudApi<TJson, TAdd1, TStorage, TApi> API) {
this.API = API;
}
public virtual IEnumerable<TJson> Get(ODataQueryOptions<TJson> options) {
var settings = new ODataValidationSettings() {
AllowedQueryOptions = AllowedQueryOptions.All
};
options.Validate(settings);
var query = API.List().AsQueryable();
var results = options.ApplyTo(query);
return (results as IQueryable<TJson>).ToList();
}
public virtual async Task<TJson> Get([FromODataUri] long key) {
var query = await API.Get(key)
.DefaultAwait()
;
return query.Response;
}
}
When using Ninject property injection the following works only if the object is instantiated by the framework (not by developer in code) so that the injection works:
public class SomeController: Controller {
[Inject]
public DbContext db {get; set;}
...
}
However when the object has to be instantiated in the code by the developer the binding does not happen (I don't wanna say fail because it does not happen).
public class DataProvision {
[Inject]
public DbContext db {get; set;}
public List<T> GetList<T>() where T: class, new() {
return db.Set<T>().toList();
}
...
}
public class Test {
public static void Test(){
DataProvision dp = new DataProvision();
var getValue = dp.GetList<Person>();
}
}
Is it even supported by Ninject and if yes what is the solution.
Justification of why we are doing this: Switching between back-up databases and active DBs effortlessly in case emergency
This is expected behavior. The DI framework has no opportunity to inject anything if you new up your own instances. If your code has access to the DI bindings, set up a kernel and use it to instantiate your class:
public class Test {
public static void Test(){
var kernel = new StandardKernel(new YourDiModule());
DataProvision dp = kernel.Get<DataProvision>();
var getValue = dp.GetList<Person>();
}
}
Using the above strategy, you'll probably need to tweak your DI configuration a little so that your context gets disposed when you want it to. (Your web application is probably normally set up to dispose the context after each web request completes, and it doesn't look like your test code is set up to run in the same kind of environment.)
Otherwise, you'll need to manage the dependency injection by hand:
public class Test {
public static void Test(){
using (var context = new DbContext()) // or however you create contexts
{
DataProvision dp = new DataProvision();
dp.db = context;
var getValue = dp.GetList<Person>();
}
}
}
I have three tables that have the following relationships between them:
Account {
public int Id;
}
Job {
public int Id;
public int AccountId;
}
Practice {
public int Id;
public int AccountId;
public string Name;
}
I would like to be able to access a Practice object through a Job object like so:
Job.Account.Practice.Name
The database structure is pre-existing, so changing it is not an option. I would like to get EF to provide access to this relationship, and I'm sure it can. I did get it to work by putting an ICollection navigation property to Practice on the Account class and annotating an Account navigation property on the Practice class with ForeignKey, but there has to be a way to do it without using a collection.
So, the question is, what data annotation attributes should I attempt to use to get the desired result?
Description
You need no DataAnnotation Attribute to do that. In Codefirst you can do the following. The Entity Framework will generate the table you described for you.
Sample
Account {
public int Id;
}
Job {
public int Id;
public virtual Account Account;
}
Practice {
public int Id;
public virtual Account Account;
public string Name;
}
If you want also a ìnt column (AccountId) in your Job / Practice Entity you can do this using the ModelBuilder. The Entity Framwork creates only one foreign key column, like you want.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Job>.HasRequired(x => x.Account).WithMany().HasForeignKey(x => x.Accountid);
//
}
More Information
ScottGu - Using EF “Code First” with an Existing Database
Update
You can use Entity Framework Power Tools CTP1 to generate the
Models from your existing Database.
I need to convert between these two classes, and want to maintain DRY but not violate the Single Responsibility Pattern...
public class Person
{
public string Name {get;set;}
public int ID {get;set;}
}
public class PersonEntity : TableServiceEntity
{
public string Name {get;set;}
public int ID {get;set;}
// Code to set PartitionKey
// Code to set RowKey
}
More Info
I have some Model objects in my ASP.NET MVC application. Since I'm working with Azure storage I see the need to convert to and from the ViewModel object and the AzureTableEntity quite often.
I've normally done this left-hand-right-hand assignment of variables in my controller.
Q1
Aside from implicit/explicit conversion, should this code be in the controller(x) or the datacontext(y)?
Person <--> View <--> Controller.ConverPersonHere(x?) <--> StorageContext.ConvertPersonHere(y?) <--> AzurePersonTableEntity
Q2
Should I do an implicit or explicit conversion?
Q3
What object should contain the conversion code?
Update
I'm also implementing WCF in this project and am not sure how this will affect your recommendation . Please also see this question.
Q1: The controller.
Q2: Convert manually or with the help of a mapping tool such as AutoMapper.
Q3: I would put the code for this in a converter or mapper class like the following. Note that IConverter is shared among all converters, and IPersonConverter just exists so your controllers and service locators can use it.
public interface IConverter<TModel, TViewModel>
{
TViewModel MapToView(TModel source);
}
public interface IPersonConverter : IConverter<PersonEntity, Person>
{
}
public class PersonConverter : IPersonConverter
{
#region IPersonConverter
public Person MapToView(PersonEntity source)
{
return new Person
{
ID = source.ID,
Name = source.Name
};
//or use an AutoMapper implementation
}
#endregion
}
I like the Validation Application Block from the Enterprise Library :-)
Now i would like to use the DataAnnotations in Winforms, as we use asp.net Dynamic Data as well. So that we have common technologies over the whole company.
And also the Data Annotations should be easier to use.
How can I do something similiar in Winforms like Stephen Walter did within asp.net MVC?
I adapted a solution found at http://blog.codeville.net/category/validation/page/2/
public class DataValidator
{
public class ErrorInfo
{
public ErrorInfo(string property, string message)
{
this.Property = property;
this.Message = message;
}
public string Message;
public string Property;
}
public static IEnumerable<ErrorInfo> Validate(object instance)
{
return from prop in instance.GetType().GetProperties()
from attribute in prop.GetCustomAttributes(typeof(ValidationAttribute), true).OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(instance, null))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty));
}
}
This would allow you to use the following code to validate any object using the following syntax:
var errors = DataValidator.Validate(obj);
if (errors.Any()) throw new ValidationException();