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
中的内容。嘿,谢谢您的回复。。当你说它将加载整个集合时。。你的意思是,针对特定客户的完整系列?好的,谢谢你,我会尝试一下并让你知道。。我真的很感谢你在回答中投入的时间和细节嘿,谢谢你的回答。。当你说它将加载整个集合时。。你的意思是,针对特定客户的完整系列?好的,谢谢你,我会尝试一下并让你知道。。我真的很感谢你在回答中投入了大量的时间和细节