I have a DocumentDataServiceContext derived from TableServiceContext. Inside that class I have the following method:
public DataServiceQuery<Document> Documents
{
get
{
return this.CreateQuery<Document>("Documents");
}
}
Is there a way to get rid of the string constant passed to CreateQuery and instead obtain the table name used by CloudTableClient.CreateTablesFromModel(typeof(DocumentDataServiceContext))?
No. At the end of the day, the CreateQuery() must have the table name to query against. You can of course use convention or reflection to derive what that table name will be in another method, but at some point a string must be passed to CreateQuery.
public DataServiceQuery<T> CreateQueryByConvention<T>()
{
return this.CreateQuery<T>(typeof(T).ToString());
}
Related
What is the correct syntax for a string expression meant to reference a call to a static function, when passed as a parameter to ExpressionEvaluatingSqlParameterSourceFactory?
As an example, I have a static function that returns a java.util.Date within a utility class:
public class DateTimeUtils {
private DateTimeUtils() {throw new IllegalStateException("Utility class");}
public static Date currentDeliveryDate() {
ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
return new DateTime(
today.getYear(),
today.getMonthValue(),
today.getDayOfMonth(),
5,
0,
0)
.toDate();
}
I want to use the result of that function as a SQL parameter. The SQL is along the lines of
select zip
from delivery_status
where delivery_date = :deliverydate
And setting the parameter goes a little something like this:
public SqlParameterSourceFactory sourceFactory() {
ExpressionEvaluatingSqlParameterSourceFactory sourceFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> params = new HashMap<>();
params.put("deliverydate", "#T(com.acme.util.DateTimeUtils).currentDeliveryDate()");
sourceFactory.setParameterExpressions(params);
return sourceFactory;
}
I've tried variations with/without T, pound sign, parenthesis, and fully qualified name, but I keep getting
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'deliverydate': No value registered for key 'deliverydate'
at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:355)
Can one of you help me with the correct incantation?
Cheers, y'all.
Must work like this:
"T(com.acme.util.DateTimeUtils).currentDeliveryDate()"
No pound sign before T operator.
I am looking for advice on where to add validation rules for domain entities, and best practices for implementation. I did search and did not find what i was looking for, or i missed it.
I would like to know what the recommended way is for validating that properties are not null, in a certain range, or length, etc... I have seen several ways using an IsValid() and other discussions about enforcing in the constructor so the entity is never in an invalid state, or using preprocessing and postprocessing, and others using FluentValidation api, how invariants impact DRY and SRP.
Can someone give me a good example of where to put these sorts of checks, when using a App Service, Bounded Context, Domain Service, Aggregate Root, Entity layering. Where does this go, and what is the best approach?
Thanks.
When modeling your domain entity, it is best to consider real-world implications. Let's say you are dealing with a Employee entity.
Employees need a name
We know that in the real-world an employee must always have a name. It is impossible for an employee not to have a name. In other words, one cannot 'construct' an employee without specifying its name. So, use parameterised constructors! We also know that an employees name cannot change - so we prevent this from even happening by creating a private setter. Using the .NET type system to verify your employee is a very strong form of validation.
public string Name { get; private set; }
public Employee(string name)
{
Name = name;
}
Valid names have some rules
Now it starts to get interesting. A name has certain rules. Let's just take the simplistic route and assume that a valid name is one which is not null or empty. In the code example above, the following business rule is not validated against. At this point, we can still currently create invalid employees! Let's prevent this from EVER occurring by amending our setter:
public string Name
{
get
{
return name;
}
private set
{
if (String.IsNullOrWhiteSpace(value))
{
throw new ArgumentOutOfRangeException("value", "Employee name cannot be an empty value");
}
name = value;
}
}
Personally I prefer to have this logic in the private setter than in the constructor. The setter is not completely invisible. The entity itself can still change it, and we need to ensure validity. Also, always throw exceptions!
What about exposing some form of IsValid() method?
Take the above Employee entity. Where and how would an IsValid() method work?
Would you allow an invalid Employee to be created and then expect the developer to check it's validity with an IsValid() check? This is a weak design - before you know it, nameless Employees are going to be cruising around your system causing havoc.
But perhaps you would like to expose the name validation logic?
We don't want to catch exceptions for control flow. Exceptions are for catastrophic system failure. We also don't want to duplicate these validation rules in our codebase. So, perhaps exposing this validation logic isn't such a bad idea (but still not the greatest!).
What you could do is provide a static IsValidName(string) method:
public static bool IsValidName(string name)
{
return (String.IsNullOrWhiteSpace(value))
}
Our property would now change somewhat:
public string Name
{
get
{
return name;
}
private set
{
if (!Employee.IsValidName(value))
{
throw new ArgumentOutOfRangeException("value", "Employee name cannot be an empty value");
}
name = value;
}
}
But there is something fishy about this design...
We now are starting to spawn validation methods for individual properties of our entity. If a property has all kinds of rules and behavior attached to it, perhaps this is a sign that we can create an value object for it!
public PersonName : IEquatable<PersonName>
{
public string Name
{
get
{
return name;
}
private set
{
if (!PersonName.IsValid(value))
{
throw new ArgumentOutOfRangeException("value", "Person name cannot be an empty value");
}
name = value;
}
}
private PersonName(string name)
{
Name = name;
}
public static PersonName From(string name)
{
return new PersonName(name);
}
public static bool IsValid(string name)
{
return !String.IsNullOrWhiteSpace(value);
}
// Don't forget to override .Equals
}
Now our Employee entity can be simplified (I have excluded a null reference check):
public Employee
{
public PersonName Name { get; private set; }
public Employee(PersonName name)
{
Name = name;
}
}
Our client code can now look something like this:
if(PersonName.IsValid(name))
{
employee = new Employee(PersonName.From(name));
}
else
{
// Send a validation message to the user or something
}
So what have we done here?
We have ensured that our domain model is always consistent. Extremely important. An invalid entity cannot be created. In addition, we have used value objects to provide further 'richness'. PersonName has given the client code more control and more power and has also simplified Employee.
I built a library that can help you.
https://github.com/mersocarlin/ddd-validation
I have the following code.
public void GetMessages(Expression<Func<IMessageQueryable, bool>> messageSpecification, string folder = "INBOX")
{
// Implementation stripped
}
How can i provide default value for messageSpecification?. Specification says the value must be a compile time constant. Is this possible?.
EDIT: Not lookig for specifying it as Expression<Func<IMessageQueryable, bool>> messageSpecification = null
You can OverLoad it. What would your default value be?
Why bother? Create an overload for the same method without messageSpecification parameter and define it's default value yourself inside the overloaded method and pass it to your original method. Default parameters are actually never meant to be used like that anyway.
public void GetMessages(string folder = "INBOX")
{
this.GetMessages(DEFAULT_VALUE, folder);
}
There are a lot of workarounds for the missing support of enumerations in the Entity Framework 4.0. From all of them I like this one at most:
http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx?PageIndex=2#comments
This workaround allows you to use enums in your LINQ queries which is what i exactly need. However, I have a problem with this workaround. I get for every complex type I'm using a new partial autogenerated class.Therefore the code does not compile any more because I already have a wrapper class with this name in the same namespace which converts betwen the backed integer in the database and the enum in my POCO classes. If I make my wrapper a partial class, the code still does not compile as it now contains two properties with the same name "Value". The only possibility is to remove the Value property by hand everytime I generate the POCO classes because the DB model changed (which during the development phase happens very often).
Do you know how to prevent a partial class to be generated out of complex property everytime the EF model changes?
Can you recommend me some other workarounds supporting enumerations in LINQ queries?
That workaround is based on the fact that you are writing your POCO classes yourselves = no autogeneration. If you want to use it with autogeneration you must heavily modify T4 template itself.
Other workaround is wrapping enum conversion to custom extension methods.
public static IQueryable<MyEntity> FilterByMyEnum(this IQueryable<MyEntity> query, MyEnum enumValue)
{
int val = (int)enumValue;
return query.Where(e => e.MyEnumValue == val);
}
You will then call just:
var data = context.MyEntitites.FilterByMyEnum(MyEnum.SomeValue).ToList();
I am using an approach based on the one described in your link without any modifications of the T4 templates. The contents of my partial wrapper classes are as follows:
public partial class PriorityWrapper
{
public Priority EnumValue
{
get
{
return (Priority)Value;
}
set
{
Value = (int)value;
}
}
public static implicit operator PriorityWrapper(Priority value)
{
return new PriorityWrapper { EnumValue = value };
}
public static implicit operator Priority(PriorityWrapper value)
{
if (value == null)
return Priority.High;
else
return value.EnumValue;
}
}
I've only changed that instead of a back store variable with enum value I am using the autogenerated int typed Value property. Consequently Value can be an auto-implemented property and EnumValue property needs to do the conversion in getter and setter methods.
My table:
create table MyTable (
Id int identity(1,1) not null,
MyStatus char(2) not null
)
insert into MyTable(MyStatus) select 'A'
Class and enum:
public class MyTable
{
public virtual int Id { get; set; }
public virtual MyTableStatus MyStatus { get; set; }
}
public enum MyTableStatus
{
A,
B
}
Mapping:
public MyTableMap()
{
Id(x => x.Id);
Map(x => x.MyStatus);
}
When I execute the following test, I get System.FormatException : Input string was not in a correct format...
[Test]
public void Blah()
{
MyTable myTable = Session.Get<MyTable>(1);
Assert.That(myTable.MyStatus, Is.EqualTo(MyTableStatus.A));
}
What is the right way to map an enum to it's string representation in the database?
Edit - I am writing my application on an existing database, which I cannot modify easily because it is used by other applications also. So some fields in the database (which I would like to represent as enums in my application) are of type int and some of type char(2).
You need to create a custom IUserType to convert an enum to its string representation and back. There's a good example in C# here and an example in VB.NET for working with enums here (scroll down to implementing IUserType).
Well as far as I am aware NHibernate stores enums as string only in the db by default. I think I know what the problem here is. The way you are creating the table is incorrect.
if you are using Nhibernate use it build configuration function to create the tables instead of creating the tables manually and then you will see that your enum is stored as string.
We use enums extensively in our app and it makes sense for us to store it as strings in the db. The reasons are simple if I add a new value to an enum tom then if default values are not set then my code and my data are tightly coupled which I definitely wouldnt want.
SimpleConfig.ExposeConfiguration(c => new SchemaExport(c).Create(false, true)).BuildConfiguration();
Also instead of using char for your string can you use varchar for the property.
After the update:
Cant you guys do some kind of manipulation before you store it in the database? Thus when you want to store the new char enums write a function that generates an int value for you and store this in the propertry and now save it or if you want to make it simple the function can have a switch case.
So what you do is you dont have a get on this property that is retrieved from the db instead you add a new property in the class Status that basically has the logic of getting the appropriate enum.
Do you think thats a good idea?
Hope this helps.