【问题标题】:Return request in web method WCFWeb方法WCF中的返回请求
【发布时间】:2015-12-31 12:51:58
【问题描述】:

我有 Web 服务和一个方法,它使用实体框架向我的表“客户”发出请求。

我想返回我的请求的结果:

[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 调用我的方法时,我没有答案。如果我删除属性 virtual Adress 那么我有一个答案,但我还需要取回地址(联合)

谢谢

【问题讨论】:

  • 猜你的型号是dbcontext 换行model.Customer.include("Adress ").Where(x =&gt; x.Name == id).First()
  • 是一样的,修改行没有答案
  • 你能解释一下你需要什么吗?
  • 返回我的查询结果。客户+地址
  • 您确定您的数据库中有与该客户相关的地址吗?

标签: c# entity-framework wcf


【解决方案1】:

如果您想在查询中显式加载一个相对属性,您可以通过使用Include 扩展方法的 Eagerly Loading 来实现:

 customer = model.Customer.Include(c=>c.Address).Where(x => x.Name == id).First();

您也可以使用显式加载:

 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 属性。因此,首先检查数据库中的关系,然后检查是否有与要加载的Customer 相关的Address。您应该能够使用我上面建议的两种变体之一来加载 Address 导航属性。

【讨论】:

  • 我在Include(c=&gt;c.Address) 中有一个错误,无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型。我的数据库中有一个关系:relationship
  • Include 方法仅适用于导航属性。您不需要对标量属性执行此操作,它们将始终在您从数据库加载实体时加载
  • 如果我提出一个简单的请求,我就有很好的自动关系:img - img
【解决方案2】:

由于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();

【讨论】:

  • 如何映射两者?谢谢。必须通过这个吗?
  • 这取决于,例如,如果您序列化为 Json,您可以使用 Newtonsoft json library,它有一些用于序列化虚拟属性的选项。但总的来说,使用 DTO 是一种很好的做法
  • 如果我在选择中写Adress = x.Adress,我没有回应
  • @Azertya 你有没有用fluent api映射客户和地址之间的关系?
  • 我的数据库中有一个关系:relationship
【解决方案3】:

我在我的班级客户中删除了关键字 virtual :

[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&lt;Customer&gt; 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 =&gt; 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>

但不实用

【讨论】:

  • 为什么不实用?这只是 xml
  • 必须更改 EntityFramework 生成的类以正确检索结果是不切实际的
  • 在您的原始课程中,在您的 Customer 模型中的 AddressId 上方添加 [ForeignKey("Adress")]。我认为你只是没有在实体框架中映射关系,所以延迟加载/急切加载是不可能的
  • 不,我没有回复。由于虚拟属性,无法序列化模型以发送它们
  • 因此我对 DTO 类的回答,老实说,您现在的解决方案非常奇怪:p
猜你喜欢
  • 2017-03-26
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
相关资源
最近更新 更多