Bind custom class to a column in database with EF 4 POCO - entity-framework

I have create a class, let's call it User. In this class I have a custom created class called EMail. This class contains only a string that holds the value of the emailadress and some logic to verify the address. So it looks like this in my User class.
public class User{
public string Name{get;set;}
public EMailAddress EMail{get;set;}
...
}
I now want to bind this EMail to a column in my databas by using EF4's CTP5 code. But I can't do this, I don't even get an good exception back, all I get is "Thread aborted exception", but if I comment out my EMail property it works good.
My EMailAddress class looks like this.
public class EMailAddress
{
//-- Declaration
private string _email;
//-- Constructor
public EMailAddress(string emailAddress)
{
if (emailAddress == null)
throw new ArgumentNullException(string.Format("Supplied emailaddress can't be null"));
if (!IsValid(emailAddress))
throw new ArgumentException(string.Format("'{0}' is not a valid Emailaddress", emailAddress));
_email = emailAddress;
}
//-- Methods
private static bool IsValid(string emailAddress)
{
Regex re = new Regex(Constants.EMAIL_REGULAR_EXPRESSION_PATTERN);
return re.IsMatch(emailAddress);
}
public override string ToString()
{
return _email;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (obj is string)
return _email == (string)obj;
if(obj is EMailAddress)
return _email == ((EMailAddress)obj).ToString();
return false;
}
public override int GetHashCode()
{
return _email.GetHashCode();
}
//-- Operator
public static bool operator ==(EMailAddress emailAddress, EMailAddress emailAddress2)
{
return object.Equals(emailAddress, emailAddress2);
}
public static bool operator !=(EMailAddress emailAddress, EMailAddress emailAddress2)
{
return !(emailAddress == emailAddress2);
}
}
And I want to keep my EMailAddress class free of any public properties. Is there a way to let the EF use the .ToString() method when itsaves the value to the database, and use the constructor when loading the data from the database to populate my objects.
Thanks...

No it is not possible. You have two choices:
Add another string property to your User class. This property will be responsible for returning email and setting email (creating EmailAddress instance). This property will be mapped. Add [NotMappedAttribute] to EMail property. You can play with visibility of the new property. In common EF you can change visibility of property but I'm not sure if it is also possible in code-first.
Map EMailAddress as complex type (mark it with [ComplexTypeAttribute] but in such case you again need to add string property to EMailAddress.

You can map non-public properties to columns in EF but the default codefirst API doesn't support it out of the box. I've made some free code available that you can use in your projects to support this need. You'll still have to have the properties but they can be protected or private or internal now.
Details are here
http://blogs.msdn.com/b/schlepticons/archive/2011/08/31/map-private-properties-with-ef-fluent-api.aspx

Related

Why does dart has got special keywords for get and set?

I am new to flutter, I was just wondering special keywords for getter and setter. Why has dart kept special keywords get and set for getter and setter respectively? Is there any particular reason, because like other languages it could have been done with simple functions also.
Example in dart we have get and set keywords.
class Person {
String _name;
String get name => _name;
set name (String val) => _name = val;
}
In java, we do the same using public methods.
// Java, No get, set keywords used
public class Person {
private String name; // private = restricted access
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String newName) {
this.name = newName;
}
}
Why do we need separate get and set keywords in dart? Is that different from a normal getter and setter methods that we use in java, cop
We could simply use
class Person {
String _name;
String getName() => _name;
void setName(String val) => _name=val;
}
I know this is something like using variables directly instead of methods, Simply my question is Is there anything that we can't achieve in a simple getter and setter methods that we can do using get and set keywords?
This is basically for convenience and backward compatibility. Let's say you start off with a public field:
class Person {
final String name;
}
but then you decide name should rather be a calculated field based on first and last name:
class Person {
final String lastName;
final String firstName;
String get name => '$firstName $lastName';
}
in java it is a best practice to never, ever have a public class member variable, just because it doesn't have a way to transition to a method without changing the API. so you ALWAYS have to write getVariable() acessor methods, even if 99% of those only have return variable; as body.

Service fabric actor state and list

Is it recommended to have a list in Service fabric actor? I am trying to keep User favorites in a User Actor. What is best approach for this scenario?
Yes, as long as you treat the list as immutable.
The state manager retrieval methods return a reference to an object in
local memory. Modifying this object in local memory alone does not
cause it to be saved durably. When an object is retrieved from the
state manager and modified, it must be reinserted into the state
manager to be saved durably.
-
The UserInfo type below demonstrates how to define an immutable type
taking advantage of aforementioned recommendations.
[DataContract]
// If you don’t seal, you must ensure that any derived classes are also immutable
public sealed class UserInfo {
private static readonly IEnumerable<ItemId> NoBids = ImmutableList<ItemId>.Empty;
public UserInfo(String email, IEnumerable<ItemId> itemsBidding = null) {
Email = email;
ItemsBidding = (itemsBidding == null) ? NoBids : itemsBidding.ToImmutableList();
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context) {
// Convert the deserialized collection to an immutable collection
ItemsBidding = ItemsBidding.ToImmutableList();
}
[DataMember]
public readonly String Email;
// Ideally, this would be a readonly field but it can't be because OnDeserialized
// has to set it. So instead, the getter is public and the setter is private.
[DataMember]
public IEnumerable<ItemId> ItemsBidding { get; private set; }
// Since each UserInfo object is immutable, we add a new ItemId to the ItemsBidding
// collection by creating a new immutable UserInfo object with the added ItemId.
public UserInfo AddItemBidding(ItemId itemId) {
return new UserInfo(Email, ((ImmutableList<ItemId>)ItemsBidding).Add(itemId));
}
}
more info: 1 and 2

Wicket - DropDownChoice from Enum to Primitive

Im having some problem with DropDownChoice.
I have an Enum with a list of school title like:
public enum StudyTitle {
NONE(null,null),ELEMENTARY("1","Elementary"),COLLEGE("2","College");
private String code;
private String description;
private StudyTitle(String code, String description){
setCode(code);
setDescription(description);
}
[setter and getter]
}
Then I have a Pojo with a String proprerty call "studyTitleCode" where I want to put the code (ex 1 for elementary, 2 for college etc...).
When I create a DropDownChoice Wicket doesn't allow me to have a proprerty Model of type String if the DropDownChoice is of type StudyTitle.
Ex.
[building the listOfStudyTitle as ArrayList of Enums]
DropDownChoice<String> studyLevel = new DropDownChoice<String>("id",new PropertyModel<String>(myPojo,"studyTitleCode"),listOfStudyTitle,new ChoiceRenderer<StudyTitle>("description","code"));
Is there a Method to allow Wicket to link one property of the Enum to the Property of Model?
Thanks
The choice options for an AbstractSingleSelectChoice must match the type of the value model. The only related config option for the DropDownChoice that I'm aware of is the IChoiceRenderer which allows you to set how the enum value is rendered (vs the default call toString()).
One option would be, instead of using the enum instance itself for your choices model, give the enum a String property that can be used:
public enum TestEnum {
ONE ("ONE"),
TWO ("TWO"),
THREE ("THREE");
private String value;
TestEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static List<String> getStringValues()
{
List<String> stringValues = new ArrayList<String>();
for (TestEnum test : values()) {
stringValues.add(test.getValue());
}
return stringValues;
}
}
#Override
protected void onInitialize() {
super.onInitialize();
IModel<String> myStringValueModel = new Model<String>();
add(new DropDownChoice<String>("id", myStringValueModel, TestEnum.getStringValues()));
}

Linq to entities and generics - unable to cast

I have two interfaces for users:
public interface IUserModel
{
int UserId {get;set;}
}
public interface IUserAuthModel : IUserModel
{
string Username {get;set;}
string Password {get;set;}
}
I have user model that implements IUserAuthModel because it requires authorization check for access:
public class UserSubscriptionModel : IUserAuthModel
{
public int UserId {get;set;}
public string Username {get;set;}
public string Password {get;set;}
public bool Subscribed {get;set;}
}
I have user repository based on EF 4.3.1 where I have method for projection:
IQueryable<T> ProjectTo<T>() where T: IUserModel
{
if(typeof(T) == typeof(UserLoginModel)
{
return db.Users.Select(x => new UserSubscriptionModel {
UserId = x.UserId,
Username = x.Username,
Password = x.Password,
Subscribed = x.Subscribed
}) as IQueryable<T>;
}
I have method that retrieves one user based on conditional expression:
T Get<T>(conditionalexpression) where T : IUserModel
{
return ProjectTo<T>.Where(conditionalexpression).FirstOrDefault();
}
I'm implementing authorization method:
public bool Authorize<T>(string username, string password, out T TUser) where T : IUserAuthModel
{
TUser = Get<T>(x => x.Username == username && x.Password == password);
... some other irrelevant code
}
And then I do the following:
UserSubscriptionModel model;
bool authorized = Authorize<UserSubscriptionModel>("hello","world", out model);
This code fails on part where it tries to extract FirstOrDefault. It says Linq to Entities supports casting primitive types.... can't cast from UserSubscriptionModel to IUserAuthModel - or other way around, can't remember. But point is, my generics are not working, even though IUserAuthModel inherits from IUserModel so if my class implements IUserAuthModel it implements IUserModel as well.
What am I missing? I'm not getting a single error/warning and I've made sure my inheritance is done properly (or at least I think so).
I'm sorry if code has some typos, I left real code at work.
Thanks for all the tips.
Entity Framework needs to know that the generic parameter that you're projecting to can be a plain ol' object or struct of some type, otherwise it'll only be able to infer it as an IUserModel. If you add another type constraint telling it T will always be one of those things (depending on your domain model; you're probably using classes though):
IQueryable<T> ProjectTo<T>() where T: class, IUserModel
(or this, if all your IUserModels are structs:)
IQueryable<T> ProjectTo<T>() where T: struct, IUserModel
that exception should go away.
See these two topics, where I found the answer:
https://stackoverflow.com/a/13701650/183350
https://stackoverflow.com/a/19847671/183350
instead of return as IQueryable try the linq Cast<>
IQueryable<T> ProjectTo<T>() where T: IUserModel
{
if(typeof(T) == typeof(UserLoginModel)
{
return db.Users.Select(x => new UserSubscriptionModel {
UserId = x.UserId,
Username = x.Username,
Password = x.Password,
Subscribed = x.Subscribed
}).Cast<T>;
}

MVC2: Validation (Data Annotations) with two field dependency

Example:
We have a conditional field.
This conditional field is a radio button with the following two values “yes” and “no”.
Lets say the name of this radiobutton is “AAA”.
This conditional field “AAA” should only be displayed when another radio button field “BBB” is set to “yes”. (Values of radio button “BBB” are also “yes” and no”) .
But the conditional field “AAA” should be displayed with NO pre-set value, means “yes” nor “no” should be set when the field is first displayed.
The problem occurs based on the requirement that the conditional field “AAA” should ONLY be required when (the non-conditional) field “BBB” is set to “yes” – and not required when the field “BBB” is set to “no”.
(Sounds, that I didn’t heard anything about an if statement, or? But hold on and continue reading ...)
Believe me, it would not be a problem for me to solve this topic when we would use the “Modelstate” – but we are talking here about Validation (Data Annotations) that looks like this here:
public class Input1FormModel
{
[Required(ErrorMessageResourceName="Error_Field_AAA_Empty",
ErrorMessageResourceType=typeof(Resources.MyDialog))]
public int AAA { get; set; }
}
I fully understand ALSO these lines of code - I believe ;-)
...
//property limits
public int UpperBound { get { return DateTime.Now.Year; } }
public int LowerBound { get { return 1900; } }
...
[NotNullValidator]
[PropertyComparisonValidator("LowerBound", ComparisonOperator.GreaterThan)]
[PropertyComparisonValidator("UpperBound", ComparisonOperator.LessThanEqual)]
public int? XYZ { get; set; }
But, how to solve the above described dependency (AAA <-> BBB)?
Changing “return DateTime.Now.Year;” to a function call which checks first the other field and returns then true or false? But how to fetch there the value of the other field?
You may need to use IDataErrorInfo.
See this question, where I answered this:
Check out IDataErrorInfo and this question I asked about IDataErrorInfo vs. DataAnnotations.
You can do this using data annotations but the annotation needs to be operating on the class level and not on the property level as validationattributes are for single properties.
Here is an example I created because post code is optional and state not required if people have said they're in New Zealand, but it is compulsory in Australia. This composite validation with take the whole model as the input value and use reflection to compare the values of the property names passed in from the data annotation.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class NZPostcodeAttribute : ValidationAttribute
{
public const string _defaultErrorMessage = "Postcode and State are required for Australian residents";
private readonly object _typeId = new object();
public NZPostcodeAttribute(string countryProperty, string postcodeProperty, string stateProperty)
{
CountryProperty = countryProperty;
PostcodeProperty = postcodeProperty;
StateProperty = stateProperty;
}
public string CountryProperty { get; private set; }
public string StateProperty { get; private set; }
public string PostcodeProperty { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return _defaultErrorMessage;
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value);
object countryValue = props.Find(CountryProperty, true).GetValue(value);
object postcodeValue = props.Find(PostcodeProperty, true).GetValue(value);
object stateValue = props.Find(StateProperty, true).GetValue(value);
string countryString = countryValue == null ? "" : countryValue.ToString();
string postcodeString = postcodeValue == null ? "" : postcodeValue.ToString();
string stateString = stateValue == null ? "" : stateValue.ToString();
bool isValid = true;
if (countryString.ToString().ToLower() == "australia")
{
if (String.IsNullOrEmpty(postcodeString) || String.IsNullOrEmpty(stateString))
{
isValid = false;
}
}
if (!String.IsNullOrEmpty(postcodeString))
{
string isNumeric = "^[0-9]+";
if (!Regex.IsMatch(postcodeString, isNumeric))
isValid = false;
}
return isValid;
}
}
When you want to apply this to your model, it needs to be done on a class level on the model (see the flag AttributeTargets.Class at the top).
Do it as follows:
[NZPostcode("Country", "Postcode", "State")]
public class UserRegistrationModel
{....
You need to point the validation attribute to the property names. It is also possible to add client side validation to this as well, but that would be a whole article on its own.
You can easily adapt the above to your scenario.