How do I conviniently consume OData service from .NET code - rest

Is there any best-practice approach/library for consuming OData services from .NET code? So that I do not have to mess with building query string and parse the response manually?
I envision something like this:
class Person
{
public string Name {get; set;}
public int Age {get; set;}
}
void Main()
{
Person person =
new ODataRequest<Person>()
.EndPoint("http://server.com/personservice")
.AddHeader("header", "value")
.AsJson()
.Where(p => p.Name.EndsWith("y") && p.Age > 21)
.Skip(10)
.Take(5)
.Send();
}
Please ignore the syntax (and that I'm mixing endpoint related stuff with query related stuff), this is just to convey the idea.
The code above would be supposed to automatically build proper OData query string with $filter, $skip, etc expressions as well as parse the response.
Has a library of this kind been already built? Or I'm on my own here?:)
Thanks!

As per Padrus' answer, the library you're looking for is definitely WCF Data Services. It has a solid code-gen experience as well as a reasonably complete LINQ provider. If you want to play with it up front with minimal investment, try out the latest betas of LINQPad (http://www.linqpad.net/Beta.aspx), which has the WCF DS client built in. To the best of my knowledge, there isn't anything else comparable out there for .NET.
Note: WCF DS is built into Visual Studio. If you use the Add Service Reference wizard to add a reference to an OData service, you will get our DLLs. Note that if you are using VS 2012, you will get references to our NuGet packages, which you can then maintain the way you maintain all of your other NuGet dependencies. If you are using VS 2010 you should still consider adding references to the NuGet packages and using NuGet to update dependencies going forward.

Related

Auto=RTrim Strings in Entity Framework, ServiceStack OrmLite, PetaPoco, etc

Edited for Clarity
I've been looking at ORMs for the last week, as well as trying to decide if I want to bother with them. At the end of the day, there seem to be about a dozen worthy contenders, of which most are fairly hard to tell apart. I eventually settled on the potential trio of EF, OrmLite and PetaPoco, all of which seem pretty good.
One feature I've been looking for is the ability to magically configure the code generator to automatically right trim all strings in the generated POCOs, without any changes to the DB. I have a database with literally thousands of records spread across hundreds of fields, and every single string field has a bunch of spaces at the end of it for legacy reasons. Those need to be stripped from the resulting POCOS/Entities to make the processing less ugly, but I can't make any changes to the DB (it's not mine), so I'm wondering if there is easy-easy way to do it.
With Entity Framework I looked a little bit at the process for Database First and Model First design, and those look like you could probably tweak the T4 template code to generate appropriate code on a case by case basis. This seems like it would be viable, but I don't want to reinvent the wheel if someone has already done it. I would just like to have the code that takes care of the problem.
For the other ORMs, I could probably pull them in the house, figure out how they work and plug-in some kind of logic that does the magic.
So does anybody have a suggestion for an ORM that has a configuration switch that can automatically right-trim all strings? It would make the database much easier to work with, hundred percent certain there is never any value in those extra spaces at the end.
Thought this was a good feature so I've just added this to ServiceStack.OrmLite where you can now add a custom filter for strings, e.g:
OrmLiteConfig.StringFilter = s => s.TrimEnd();
public class Poco
{
public string Name { get; set; }
}
using (var db = OpenDbConnection())
{
db.DropAndCreateTable<Poco>();
db.Insert(new Poco { Name = "Value with trailing " });
var row = db.Select<Poco>().First();
Assert.That(row.Name, Is.EqualTo("Value with trailing"));
}
It will be in the next v4.0.19+ NuGet release of ServiceStack, which is now available on ServiceStack's MyGet Feed.
With Entity Framework (and possibly PetaPoco which I don't know personally) you should be able to modify the T4 template and add read-only properties to your entities, returning the trimmed value of database-related property.
public string Name
{
get { return this.DbName.TrimEnd(); }
}
But...
You have to find a way to do this for string properties only (I think one of the methods that are visible in the T4 template can be used for that, but I'm not sure).
Modifying T4 templates is something you may have to do again when updates are released.
You can't use the read-only properties directly in LINQ-to-entities because EF can't translate them into SQL. You'll alway have to use them after an AsEnumerable() call.

EF naming, is there a setting to change all field names to lower case?

When use EF with breezejs, seems server side should have each name starts with upper case, and on client side, use camel style, like
FirstName on EF and
firstName on client side.
I think it is not as good as all lower case, everyone can understand firstname, not necessary FirstName or firstName.
I wonder if it is strongly suggested to not use all lower case name? If I want to use all lower case name, is there a way to tell EF (database first) to create class with all lower case name no matter what they are on the db side?
Thanks
I think you should do this within your JSON serialization and deserialization. If you're using Web API you can do this. From OdeToCode:
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
If you don't want to do this with your JSON serialization, then if you're using EF6 code first you can do some custom conventions to achieve this for your column names. Do something similar for tables.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Properties()
.Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name.ToLower()));
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Configurations.Add(new UserHashHistoryConfiguration());
}
See this post on MSDN for more information on custom conventions in EF6.
This is what the Breeze NamingConvention is for.
See: http://www.breezejs.com/documentation/naming-convention
But you may have a problem because the NamingConvention needs to be able to roundtrip your name. i.e. passing from server name to client name and back to server name needs to get back to the original name. With your rule there is no way to get from an all lowercase name back to the original server name unless you are willing to keep a map of all previously mapped names or come up with some other heuristic.
The example below demonstrates the issue.
var lowerCaseNamingConvention = new breeze.NamingConvention({
serverPropertyNameToClient: function (serverPropertyName, prop) {
return serverPropertyName.toLowerCase();
}
clientPropertyNameToServer: function (clientPropertyName, prop) {
// need to get back to original name here
return clientPropertyName. ???
}
});
lowerCaseNamingConvention.setAsDefault();
I'm not clear on why you want to change the property names on the server-side. Property names in .NET classes are expected to be PascalCase.
You're free to do as you please and name the properties as you wish in the EF mapper. It's harder to do in EF Database First; you can use the designer to map each property name exactly as you want to see it but wow is that time consuming. There are advanced techniques with T4 that might be better if your model is huge (beware: you can spend more time writing/debuggin T4 than just slogging through and mapping the property names by hand).
If you were willing to go with Code First, you could take a look at EF 6 custom conventions which appear to be sufficiently flexible and powerful.
You DO realize that this is not a breeze question, right? The Breeze NamingConvention (mentioned by others) is the proper place to make your client-side properties look the way you want them to look.
There isn't always a way to calculate the transform; sometimes you just have to provide a dictionary in your NamingConvention.
However, you seem to want to handle this by remaking the classes on the server. That (as you've noted) is harder and/or tedious. There is nothing Breeze can do about that.
p.s.: using JSON.NET configuration to try to cope with this during serialization will not work. You want property names that you can reference in queries and JSON.NET does nothing to morph the property names mentioned in query strings.

Using Code First and Database First Entity Framework with Devart

I have one website that uses EF 4.4 (.NET 4.0 version of EF 5.0) that uses Code First against an existing database. I use the Devart oracle data provider which requires a workaround because of casing issues with the model type.
It makes the Devart provider recognize lowercase datatypes to interpret the schema. (Or something along those lines)
This works properly, until the control within this website, built on EF 4.1 Database First (Also against an existing database) tries to load. The Devart provider seems to be shared across the websites, and it results in errors about the provider not being able to recognize the datatypes (correctly) in all caps, because of the previous workaround to make it work in Code First.
Is there a workaround for this, or do I have to convert the Database First approach to Code First?
Edit: Here is the related workaround code. I seem to have lost the forum post I got it from. I believe it was on the Devart forums:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
config.Workarounds.ColumnTypeCasingConventionCompatibility = true;
... initialization code here ...
base.OnModelCreating(modelBuilder);
}
And the related error is this:
System.Data.MetadataException: Schema specified is not valid. Errors:
Model.ssdl(205,6) : error 0040: The Type CHAR is not qualified with a namespace or alias. Only primitive types can be used without qualification.
Model.ssdl(206,6) : error 0040: The Type VARCHAR2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
There are a bunch more, but they're all the same error with different lines and data types.
The Devart provider seems to be shared across the websites
After the ColumnTypeCasingConventionCompatibility option is set, it determines the behaviour of the current application domain (web site). The process (web server) may run several application domains with different values of ColumnTypeCasingConventionCompatibility.
The value of ColumnTypeCasingConventionCompatibility for the particular application domain depends on the Fluent Mapping property of the DbContext template used for the model in web site. Fluent Mapping=true must be used with ColumnTypeCasingConventionCompatibility=true, and vice versa: Fluent Mapping=false must be used with ColumnTypeCasingConventionCompatibility=false.
You can set ColumnTypeCasingConventionCompatibility for a web site in the following alternative ways:
a) in your code before the first usage of the context (e.g., in a static constructor of the context or in the Main method of your program, etc)
b) in *.config. For example:
<configuration>
<configSections>
<section name="Devart.Data.Oracle.Entity"
type="Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfigurationSection,
Devart.Data.Oracle.Entity, Version=7.5.179.0, Culture=neutral,
PublicKeyToken=09af7300eec23701" />
</configSections>
<Devart.Data.Oracle.Entity xmlns="http://devart.com/schemas/Devart.Data.Oracle.Entity/1.0">
<CodeFirstOptions ColumnTypeCasingConventionCompatibility="true"/>
</Devart.Data.Oracle.Entity>
</configuration>

EF 4.3.1 IMigrationMetadata.Target strings are causing "No logical space left to create more user strings." compile errors

We've generated ~80 migrations since the release of the 4.3.x version of Entity Framework. Each time we generate a new migration, EF gens a snapshot of the current model for the IMigrationMetadata.Target property.
Since each migration is adding ~135k characters to our assembly, we are starting to hit critical mass. We're now receiving a "No logical space left to create more user strings." compiler error. Combine that w/ the pre-compile views, and you've got a lot of strings.
What's the best long term approach to using EF migrations with a complex model?
Maybe add-migration should be generating these w/ resource files.
we had the same issue. We are also fix this using moving the generated string into resource:
public sealed partial class RegionalCenterRenameClass : IMigrationMetadata
{
// Skipped code
string IMigrationMetadata.Target
{
get { return Targets.M201207110918331_RegionalCenterRenameClass; }
}
}
where Targets - is resource file (resx).
Thanks for reporting this. I have added this issue to our backlog for EF6.
For now, replacing the string with a resource lookup is the best workaround I can think of.

Is newest version of MS Enterprise Library compatible with older versions like 3.1

This current project I've been assigned uses the Version 3.1 levels of:
Microsoft.Practices.EnterpriseLibrary.Common;
Microsoft.Practices.EnterpriseLibrary.Data;
As I try to get to know more about the capabilities of the Ent Lib, I am running into lots of articles and doc about various versions (3.1, 4.0, and 5.0 I think).
In general do the newer versions work with application code written for an earlier release of the Ent Lib? I haven't surveyed all of the source code in this app I've inherited but I think only the "basics" of the Data Access Application Block are being used. Here is a typical piece of code:
public override List<Erx.Action> GetAll(bool bIsActive)
{
Database db = null;
DbCommand cmd = null;
List<Erx.Action> lst = null;
IDataReader iRdr = null;
try
{
db = DatabaseFactory.CreateDatabase();
cmd = db.GetStoredProcCommand("Mst_GetAllCorrectiveAction");
db.AddInParameter(cmd, "#CorrectiveActionID", DbType.Int32, -1);
db.AddInParameter(cmd, "#IsActive", DbType.Boolean, bIsActive);
iRdr = db.ExecuteReader(cmd);
lst = new List<Erx.Action>();
while (iRdr.Read())
{
Action objAction = new Action();
objAction.CorrectiveAction = iRdr["CorrectiveAction"].ToString();
objAction.CorrectiveActionID = int.Parse(iRdr["CorrectiveActionID"].ToString());
objAction.IsActive = (bool)iRdr["IsActive"];
lst.Add(objAction);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
db = null;
iRdr.Close();
if (cmd != null)
{
cmd.Dispose(); cmd = null;
}
}
return lst;
}
Frankly, this does not seem to offer much beyond regular ADO.Net but maybe the newer versions make things simpler (I've heard some very good stuff about Unity).
I just installed Ent Lib 4.1 and dug closely into the doc and found this in the "Introduction to the Data Access Application Block":
Changed Features, Version 3.1 and Later
In general, applications built using earlier releases of the Data Access Application Block will function with this release without the need for any code changes. It may be necessary to update the references to refer to the new assemblies and to update the configuration files to reference the correct version of the assemblies. However, some changes were made to the Data Access Application Block in version 3.1 (May 2007), which may affect applications written for earlier versions if you upgrade to the current version of Enterprise Library. The following sections describe these changes.
The .NET Framework 2.0 TransactionScope Class
To take advantage of the .NET Framework 2.0 TransactionScope class, there have been changes to some of the Database class methods in version of Enterprise Library from version 3.1 onwards. These methods, such as ExecuteNonQuery, have been modified to recognize when a TransactionScope instance is active by replacing the GetConnection method with the GetOpenConnection method. If you have written a class that inherits from the Database class, you will need to rewrite your code to take these changes into account. If you continue to use the GetConnection method, you will receive a compiler warning. In addition, if your application uses the ExecuteXmlReader method, you may need to rewrite your code to test to see whether a TransactionScope instance is active before closing a connection.
For more information, see Using the TransactionScope Class. For an example of how to use the ExecuteXMLReader method, see Retrieving Multiple Rows As XML.
strong text
SQL Server Compact Edition
Enterprise Library 3.1 – May 2007 and later supports SQL Server Compact Edition (CE). SQL Server CE provides the essential features of a relational database and is intended for desktop and mobile applications that need a local data store but do not require the full functionality of SQL Server. For more information, see the section "Using SQL Server CE" in Creating a Database Object.
I am still trying to get a sense of how truly useful this DAAB is. It seems like a tremendous amount of reading of doc is required to end up writing just a little less code than otherwise required with ADO.NET un-aided by the DAAB. I guess if one wanted to provide for an easier switch to say, Oracle [from MS SQL Server), this is a useful way to configure things.
If you have unit tests,port to new and run and see,if you have Resharper it can analyse your solution in VStudio and point out the errors.It will take you time.