I often stumble upon code checking values on enumerations to determine the state of some object or rule. At best, this code is extracted and put in a helper or utils class of some sort. Don’t! Use extension methods instead. It let’s you provide a name for the condition (rule) that you are checking, and it put’s it together with the enumeration.
Example
Lets say I have an enumeration with storage providers. Each provider might be able to store data virtually, hence I need the possibility of determining if it’s capable of this.
[Serializable]
public enum StorageProviders
{
LuceneIo = 0,
LuceneVirtual = 1
}
public static class StorageProvidersExtensions
{
public static bool IsVirtual(this StorageProviders provider)
{
return provider == StorageProviders.LuceneVirtual;
}
}
I can now act on the enumeration value it self.
...connectionInfo.ProviderType.IsVirtual()...
//Daniel
Advertisement
I was looking at your code first EF4. Ran into a lot of trouble mapping the entities correctly, for some reason the complete object graph is not being persisted when doing update below are the entities and their mapping
which are an extension of your sample
public interface IEfEntity
{
int Id { get; set; }
byte[] Version { get; set; }
}
public abstract class EfEntity : IEfEntity
{
public virtual int Id { get; set; }
public virtual byte[] Version { get; set; }
}
[Serializable]
public class EfCustomer
: EfEntity
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public ICollection Addresses { get; set; }
public ICollection CustomerPhones { get; set; }
public string Name
{
get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); }
}
public EfCustomer()
{
Addresses = new List();
CustomerPhones = new List();
}
}
public class EfAddress : EfEntity
{
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string ZipCode { get; set; }
public virtual string State { get; set; }
public virtual EfCustomer Customer { get; set; }
public virtual int Customer_Id { get; set; }
}
public class EfCustomerPhone : EfEntity
{
public virtual bool IsActive { get; set; }
public virtual EfCustomer Customer { get; set; }
public ICollection Phones { get; set; }
public virtual int Customer_Id { get; set; }
public virtual void PhoneAdd(EfPhone efPhone)
{
Phones.Add(efPhone);
}
public EfCustomerPhone()
{
// Phones = new List();
}
}
public class EfPhone : EfEntity
{
public virtual string PhoneNumber { get; set; }
public virtual EfCustomerPhone CustomerPhone { get; set; }
public virtual int CustomerPhone_Id { get; set; }
}
[Serializable]
public abstract class EntityMapping : EntityConfiguration where T : EfEntity
{
protected EntityMapping()
{
HasKey(o => o.Id);
Property(o => o.Id)
.IsIdentity();
Property(o => o.Version)
.IsConcurrencyToken()
.IsRequired()
.HasStoreType("timestamp")
.StoreGeneratedPattern = StoreGeneratedPattern.Computed;
}
}
[Serializable]
public class CustomerMapping : EntityMapping
{
public CustomerMapping()
{
Property(o => o.Firstname)
.HasMaxLength(100)
.IsUnicode()
.IsOptional();
Property(o => o.Lastname)
.HasMaxLength(100)
.IsUnicode()
.IsOptional();
Relationship(u => u.Addresses).FromProperty(p => p.Customer);
Relationship(u => u.CustomerPhones).FromProperty(p => p.Customer);
}
}
[Serializable]
public class AddressMapping : EntityMapping
{
public AddressMapping()
{
Property(o => o.Address1)
.HasMaxLength(100)
.IsUnicode()
.IsRequired();
Property(o => o.Address1)
.HasMaxLength(100)
.IsUnicode()
.IsOptional();
Property(o => o.City)
.HasMaxLength(24)
.IsUnicode()
.IsRequired();
Property(o => o.State)
.HasMaxLength(2)
.IsUnicode()
.IsRequired();
Property(o => o.ZipCode)
.HasMaxLength(12)
.IsUnicode()
.IsRequired();
Relationship(p => p.Customer).IsRequired()
.IsRequired();
// Register Inverses mapping
Relationship(p => p.Customer).FromProperty(u => u.Addresses);
//FK mapping for reverse lookup
Relationship(p => p.Customer).FromProperty(b => b.Addresses).HasConstraint((p, b) => p.Customer_Id == b.Id);
}
}
[Serializable]
public class PhoneMapping : EntityMapping
{
public PhoneMapping()
{
Property(o => o.PhoneNumber)
.HasMaxLength(100)
.IsUnicode()
.IsRequired();
Relationship(p => p.CustomerPhone).IsRequired();
// Register some Inverses
Relationship(p => p.CustomerPhone).FromProperty(p => p.Phones);
//MapSingleType(p => new
// {
// id = p.Id,
// phoneNumber = p.PhoneNumber,
// version = p.Version,
// customerPhone = EntityMap.Related(c => c.Phones).Id
// });
Relationship(p => p.CustomerPhone).FromProperty(b => b.Phones).HasConstraint((p, b) => p.CustomerPhone_Id == b.Id);
}
}
[Serializable]
public class CustomerPhoneMapping : EntityMapping
{
public CustomerPhoneMapping()
{
Property(o => o.IsActive);
Relationship(p => p.Customer).IsRequired()
.IsRequired();
// Register Inverses mapping
Relationship(p => p.Customer).FromProperty(u => u.CustomerPhones);
Relationship(u => u.Phones).FromProperty(p => p.CustomerPhone).IsRequired();
//FK mapping for reverse lookup
Relationship(p => p.Customer).FromProperty(b => b.CustomerPhones).HasConstraint((p, b) => p.Customer_Id == b.Id);
}
}
Hi,
It’s because EF doesn’t allow you to “reuse” mappings via inheritance, unless the members are “simple properties”, e.g. strings, ints….
E.g. CustomerMapping which has relationships will break.
The EF team knows about this.
//Daniel