考虑一个域,其中客户,公司,员工等具有ContactInfo属性,而该属性又包含一组地址,电话,电子邮件等,等等。

这是我的缩写ContactInfo:

public class ContactInfo : Entity<int>
{
    public ContactInfo()
    {
        Addresses = new HashSet<Address>();
    }

    public virtual ISet<Address> Addresses { get ; private set; }

    public Address PrimaryAddress
    {
        get { return Addresses.FirstOrDefault(a => a.IsPrimary); }
    }

    public bool AddAddress(Address address)
    {
        // insure there is only one primary address in collection
        if (address.IsPrimary)
        {
            if (PrimaryAddress != null)
            {
                PrimaryAddress.IsPrimary = false;
            }
        }
        else
        {
            // make sure the only address in collection is primary
            if (!Addresses.Any())
            {
                address.IsPrimary = true;
            }
        }
        return Addresses.Add(address);
    }
}

一些注意事项(我不确定这些是EF“最佳做法”还是100%):

地址的
  • 集合是虚拟的,允许延迟加载
  • 收集中的私有(private)二传手禁止收集替换
  • 集合是一个ISet,可确保每个联系人没有重复的地址
  • 使用AddAddress方法,我可以确保始终有一个至多1个主要地址。...

  • 我想(如果可能)阻止通过ContactInfo.Addresses.Add()方法添加地址,并强制使用ContactInfo.AddAddress(Address address) ...

    我正在考虑通过ReadOnlyCollection公开地址集,但是这可用于Entity Framework(v5)吗?

    我将如何处理?

    最佳答案

    一种方法是使ICollection属性受到保护,并创建一个仅返回ICollection属性列表的IEnumerable新属性。

    这样做的缺点是您无法像通过获取居住在该城市的所有contactinfo一样通过ContactInfo查询地址。

    这是不可能的:

    from c in ContactInfos
    where c.Addresses.Contains(x => x.City == "New York")
    select c
    

    代码:
    public class ContactInfo : Entity<int>
    {
        public ContactInfo()
        {
            Addresses = new HashSet<Address>();
        }
    
        protected virtual ISet<Address> AddressesCollection { get ; private set; }
    
        public IEnumerable<Address> Addresses { get { return AddressesCollection; }}
    
        public Address PrimaryAddress
        {
            get { return Addresses.FirstOrDefault(a => a.IsPrimary); }
        }
    
        public bool AddAddress(Address address)
        {
            // insure there is only one primary address in collection
            if (address.IsPrimary)
            {
                if (PrimaryAddress != null)
                {
                    PrimaryAddress.IsPrimary = false;
                }
            }
            else
            {
                // make sure the only address in collection is primary
                if (!Addresses.Any())
                {
                    address.IsPrimary = true;
                }
            }
            return Addresses.Add(address);
        }
    }
    

    10-02 18:42