Entity framework 如何修改此实体框架代码?

Entity framework 如何修改此实体框架代码?,entity-framework,.net-4.0,ef-code-first,Entity Framework,.net 4.0,Ef Code First,我是全新的实体框架代码第一,所以任何帮助或指导将不胜感激 我目前有以下课程: public partial class Customer { public int Id { get; set; } private ICollection<Address> _addresses; } public partial class Address { public int Id { get; set; } public string Street { get

我是全新的实体框架代码第一,所以任何帮助或指导将不胜感激

我目前有以下课程:

public partial class Customer
{
    public int Id { get; set; }
    private ICollection<Address> _addresses;
}

public partial class Address
{
    public int Id { get; set; }
    public string Street { get; set; };
    public string City { get; set; };
    public string Zip { get; set; };
}
因此,Customer.Addresses[“ABC”]将返回ID为A1和A2的地址集合。而Customer.Addresses[“XYZ”]将返回ID为A2的地址集合


任何指导/帮助都将不胜感激。。。谢谢。

据我所知,在索引器中引入这样的导航属性是不可能的。您的索引器实际上是一个查询,您必须将其表示为一个查询。我看到的唯一方法是保持导航集合不变,并引入第二个(未映射)属性,该属性将导航集合用于过滤器。最大的缺点是,这样的过滤器将在使用LINQ to对象的内存中发生,并且要求在过滤集合之前,始终首先从数据库加载完整集合(例如,通过急切或延迟加载)

我可能会将这样的过滤器排除在实体本身之外,并在存储库或服务类中实现它,或者通常在从数据库加载实体的位置/模块中实现它

您需要做的第一件事是在模型中将
customeraddress
表作为一个实体公开,因为使用附加的自定义属性
CompanyCode
您不能再使用多对多关系,而是需要两个一对多关系。新实体将如下所示:

public partial class CustomerAddress
{
    public int CustomerId { get; set; }
    // public Customer Customer { get; set; } // optional

    public int AddressId { get; set; }
    public Address Address { get; set; }

    public string CompanyCode { get; set; }
}
客户
需要更改为:

public partial class Customer
{
    public int Id { get; set; }
    public ICollection<CustomerAddress> CustomerAddresses { get; set; }
}
并为新实体创建新映射:

public CustomerAddressMap()
{
    this.ToTable("CustomerAddresses");
    this.HasKey(ca => new { ca.CustomerId, ca.AddressId, ca.CompanyCode });
    // or what is the PK on that table?
    // Maybe you need an Id property if this key isn't unique

    this.HasRequired(ca => ca.Address)
        .WithMany()
        .HasForeignKey(ca => ca.AddressId);
}
现在,在某些服务类中,您可以加载过滤后的地址:

public List<Address> GetAddresses(int customerId, string companyCode)
{
    return context.CustomerAddresses.Where(ca =>
        ca.CustomerId == customerId && ca.CompanyCode == companyCode)
        .ToList();
}
public Customer GetCustomer(int customerId, string companyCode)
{
    var customer = context.Customer.SingleOrDefault(c => c.Id == customerId);
    if (customer != null)
        context.Entry(customer).Collection(c => c.CustomerAddresses).Query()
            .Where(ca => ca.CompanyCode == companyCode)
            .Load();
    return customer;
}
最后一个示例是两个数据库查询

Customer
实体中,您可以使用帮助器属性将地址投影到
CustomerAddresses
集合之外:

public partial class Customer
{
    public int Id { get; set; }
    public ICollection<CustomerAddress> CustomerAddresses { get; set; }

    public IEnumerable<Address> Addresses
    {
        get
        {
            if (CustomerAddresses != null)
                return CustomerAddresses.Select(ca => ca.Address);
            return null;
        }
    }
}
公共部分类客户
{
公共int Id{get;set;}
公共ICollection CustomerAddresses{get;set;}
公共IEnumerable地址
{
得到
{
if(CustomerAddresses!=null)
返回CustomerAddresses.Select(ca=>ca.Address);
返回null;
}
}
}

请记住,此属性不会查询数据库,并且结果依赖于已加载到
CustomerAddresses

中的内容。据我所知,不可能使用索引器引入此类导航属性。您的索引器实际上是一个查询,您必须将其表示为一个查询。我看到的唯一方法是保持导航集合不变,并引入第二个(未映射)属性,该属性将导航集合用于过滤器。最大的缺点是,这样的过滤器将在使用LINQ to对象的内存中发生,并且要求在过滤集合之前,始终首先从数据库加载完整集合(例如,通过急切或延迟加载)

我可能会将这样的过滤器排除在实体本身之外,并在存储库或服务类中实现它,或者通常在从数据库加载实体的位置/模块中实现它

您需要做的第一件事是在模型中将
customeraddress
表作为一个实体公开,因为使用附加的自定义属性
CompanyCode
您不能再使用多对多关系,而是需要两个一对多关系。新实体将如下所示:

public partial class CustomerAddress
{
    public int CustomerId { get; set; }
    // public Customer Customer { get; set; } // optional

    public int AddressId { get; set; }
    public Address Address { get; set; }

    public string CompanyCode { get; set; }
}
客户
需要更改为:

public partial class Customer
{
    public int Id { get; set; }
    public ICollection<CustomerAddress> CustomerAddresses { get; set; }
}
并为新实体创建新映射:

public CustomerAddressMap()
{
    this.ToTable("CustomerAddresses");
    this.HasKey(ca => new { ca.CustomerId, ca.AddressId, ca.CompanyCode });
    // or what is the PK on that table?
    // Maybe you need an Id property if this key isn't unique

    this.HasRequired(ca => ca.Address)
        .WithMany()
        .HasForeignKey(ca => ca.AddressId);
}
现在,在某些服务类中,您可以加载过滤后的地址:

public List<Address> GetAddresses(int customerId, string companyCode)
{
    return context.CustomerAddresses.Where(ca =>
        ca.CustomerId == customerId && ca.CompanyCode == companyCode)
        .ToList();
}
public Customer GetCustomer(int customerId, string companyCode)
{
    var customer = context.Customer.SingleOrDefault(c => c.Id == customerId);
    if (customer != null)
        context.Entry(customer).Collection(c => c.CustomerAddresses).Query()
            .Where(ca => ca.CompanyCode == companyCode)
            .Load();
    return customer;
}
最后一个示例是两个数据库查询

Customer
实体中,您可以使用帮助器属性将地址投影到
CustomerAddresses
集合之外:

public partial class Customer
{
    public int Id { get; set; }
    public ICollection<CustomerAddress> CustomerAddresses { get; set; }

    public IEnumerable<Address> Addresses
    {
        get
        {
            if (CustomerAddresses != null)
                return CustomerAddresses.Select(ca => ca.Address);
            return null;
        }
    }
}
公共部分类客户
{
公共int Id{get;set;}
公共ICollection CustomerAddresses{get;set;}
公共IEnumerable地址
{
得到
{
if(CustomerAddresses!=null)
返回CustomerAddresses.Select(ca=>ca.Address);
返回null;
}
}
}

请记住,此属性不会查询数据库,结果取决于已加载到
CustomerAddresses
中的内容。嘿,谢谢您的回复。。当你说它将加载整个集合时。。你的意思是,针对特定客户的完整系列?好的,谢谢你,我会尝试一下并让你知道。。我真的很感谢你在回答中投入的时间和细节嘿,谢谢你的回答。。当你说它将加载整个集合时。。你的意思是,针对特定客户的完整系列?好的,谢谢你,我会尝试一下并让你知道。。我真的很感谢你在回答中投入了大量的时间和细节