我有Web服务和一个方法,它通过Entity Framework向我的表'Customer'发出请求。
我想返回我的请求结果:
[WebMethod]
public Customer MyMethod(int id)
{
Model model = new Model();
Customer customer = new Customer();
try
{
customer = model.Customer.Where(x => x.Name == id).First();
}
catch (Exception ex)
{
throw new System.NullReferenceException(ex.Message, ex.InnerException);
}
return customer;
}
我的班级客户(由EF生成):
[Table("Customer")]
public partial class Customer
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
public int? Adress_id { get; set; }
public virtual Adress Adress { get; set; }
}
班级地址(由EF生成):
[Table("Adress")]
public partial class Adress
{
public Adress()
{
Customer = new HashSet<Customer>();
}
public int Id { get; set; }
[Column("Adress")]
[StringLength(255)]
public string Adress1 { get; set; }
[StringLength(50)]
public string Town { get; set; }
public virtual ICollection<Customer> Customer{ get; set; }
}
但是当我用SoapUI调用我的方法时,我没有答案。如果我删除虚拟Adress
属性,那么我有一个答案,但我还需要取回地址(联合)
谢谢
答案 0 :(得分:0)
由于virtual
属性,无法将模型序列化以发送它们。您在客户中的地址引用了客户,这再次引用了地址......这是一个无限循环。因此,您可以使用DTO(数据传输对象)类来传输数据。对于您的Customer
模型,它看起来像这样:
public class CustomerDTO
{
public int Id { get; set; }
public string Name { get; set; }
public int? Adress_id { get; set; }
public Adress Adress { get; set; }
}
在通过WCF发送之前,您必须将Customer
转换为CustomerDTO
个对象。您甚至可以使用linq在一个语句中执行此操作:
var obectToTransfer = db.Customers.Where(c => c.Id == 5)
.Select(c => new CustomerDTO
{
Id = c.Id
...
}).FirstOrDefault();
答案 1 :(得分:0)
如果要在查询中明确加载相对属性,可以通过使用Include
扩展方法的Eagerly Loading来实现:
customer = model.Customer.Include(c=>c.Address).Where(x => x.Name == id).First();
您也可以使用Explicit Loading:
customer = model.Customer.Where(x => x.Name == id).First();
context.Entry(customer).Reference(p => p.Address).Load();
现在我建议您检查数据库中的关系。如果您没有使用Fluent Api来配置该关系,那么EF不知道Address_id
是该关系的FK。如果外键属性名为[Target Type Key Name]
,[Target Type Name] + [Target Type Key Name],
或[Navigation Property Name] + [Target Type Key Name]
,则会按惯例发现它。覆盖此约定的一种方法是使用ForeignKey
属性。因此,首先检查数据库中的关系,然后检查是否有Address
与您要加载的Customer
相关联。您应该能够使用我上面建议的两种变体之一加载Address
导航属性。
答案 2 :(得分:0)
我在班级客户中删除了关键字虚拟:
[Table("Customer")]
public partial class Customer
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
public int? Adress_id { get; set; }
public Adress Adress { get; set; }
}
我删除了我的类Adress中的构造函数和属性ICollection<Customer> Customer
[Table("Adress")]
public partial class Adress
{
public int Id { get; set; }
[Column("Adress")]
[StringLength(255)]
public string Adress1 { get; set; }
[StringLength(50)]
public string Town { get; set; }
}
我的查询:customer = model.Customer.Include("Adress").Where(x => x.Id == 2).First();
有效!
我的回答:
<a:Adress>
<a:Adress1>101 Madison Ave</a:Adress1>
<a:Id>1</a:Id>
<a:Town>New York</a:Town>
</a:Adress>
<a:AdressId>1</a:AdressId>
<a:Name>John</a:Name>
<a:Id>2</a:Id>
但它不实用