【问题标题】:What am I doing wrong? wcf & entity-framework我究竟做错了什么? wcf & 实体框架
【发布时间】:2011-08-25 00:05:47
【问题描述】:

我今天刚遇到WCF 并开始学习它。但是,一旦我尝试将它与EntityFramework 结合使用,它就停止了工作。我为我的数据库dtcinvoicerdb 创建了一个实体模型,关闭了代码生成并自己编写了Entity/ObjectContext 类。该服务应该从数据库中获取所有Employees

一切正常,项目编译并打开 WcfTestClient,但是当我尝试调用 GetEmployees() 操作时,出现以下异常:

Mapping and metadata information could not be found for EntityType 'DtcInvoicerDbModel.Employee'.

我知道下面有很多代码,但都是非常基本的,所以请耐心等待。

entity image and model properties http://img716.imageshack.us/img716/1397/wcf.png

/Entities/DtcInvoicerDbContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Objects;

using DtcInvoicerDbModel;

namespace DtcInvoicerServiceLibrary
{
    public class DtcInvoicerDbContext:ObjectContext
    {
        public DtcInvoicerDbContext():base("name=DtcInvoicerDbEntities", "DtcInvoicerDbEntities")
        {
        }

        #region public ObjectSet<Employee> Employees;
        private ObjectSet<Employee> _Employees;
        public ObjectSet<Employee> Employees
        {
            get
            {
                return (_Employees == null) ? (_Employees = base.CreateObjectSet<Employee>("Employees")) : _Employees;
            }
        }
        #endregion
    }
}

/Entities/Employee.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Objects.DataClasses;
using System.Runtime.Serialization;

namespace DtcInvoicerDbModel
{
    [DataContract]
    public class Employee
    {
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public string Username { get; set; }
        [DataMember]
        public string Password { get; set; }
        [DataMember]
        public DateTime EmployeeSince { get; set; }
    }
}

/IDtcInvoicerServicer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;

using DtcInvoicerDbModel;

namespace DtcInvoicerServiceLibrary
{
    [ServiceContract]
    public interface IDtcInvoicerService
    {
        [OperationContract]
        List<Employee> GetEmployees();
    }
}

/DtcInvoicerService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;

using DtcInvoicerDbModel;

namespace DtcInvoicerServiceLibrary
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, IncludeExceptionDetailInFaults=true)]
    public class DtcInvoicerService:IDtcInvoicerService
    {
        private DtcInvoicerDbContext db = new DtcInvoicerDbContext();

        public List<Employee> GetEmployees()
        {
            return db.Employees.Where(x => x.ID > 0).ToList();
        }
    }
}

【问题讨论】:

    标签: c# wcf entity-framework poco wcf-data-services


    【解决方案1】:

    我知道这并不能回答您的问题,但是通过您的服务,您是否考虑过使用 WCF Data Services 代替?您的服务正在将您的实体返回给您的客户——WCF 数据服务可以为您提供该服务,并让您的客户能够使用 LINQ 查询来过滤和/或投影您的结果。

    您可以将 WCF 数据服务项 (InvoicerService.svc) 添加到您的项目中并像这样设置服务类:

    public class InvoicerService : DataService<DtcInvoicerDbEntities>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("Employees", EntitySetRights.AllRead);
    
            config.SetEntitySetPageSize("*", 25);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
    

    然后您可以使用 URL 通过 GET 请求访问您的员工:

    http://server:port/InvoicerService.svc/Employees?$filter=ID gt 0
    

    同样,这不是您问题的答案,而是另一种选择。只是想我会添加它。

    希望这会有所帮助!

    【讨论】:

    • 嘿,感谢您的努力。我实际上没有考虑过(主要是因为我对此一无所知)。我正在查看您给我的链接,我相信它至少会帮助或教会我一些新的东西。再次感谢! :)
    • 没问题。如果您还有其他问题,请告诉我。我是 WCF 数据服务的粉丝,我认为它没有得到应有的关注。 :)
    • 我确实有一个问题。我的计划是创建一个 WCF 服务,该服务从数据库中获取数据,并将其提供给客户端,并在每个 EntityType 中以某种 Dictionary/Collection 的形式存储它。客户端应用程序弄乱了实体,然后将数据发送回服务,服务将更改提交到数据库AND 将更新/更改的对象发送到 all 连接的客户端并替换集合中的旧版本。然后还有其他细节,例如在客户端编辑对象时锁定对象。话虽如此
    • 老实说,如果您正在尝试这样做,您可能需要考虑数据服务。 HTTP 动词有助于描述您正在尝试执行的操作(POST=insert、PUT=update 等),并且有各种平台的客户端库可以帮助您完成此操作。查看odata.org/developers/odata-sdk 了解各种客户端库;查看 msdn.microsoft.com/en-us/library/cc668772%28VS.100%29.aspx 以获取有关客户端应用程序的各种 .NET WCF 数据服务操作的参考。希望这会有所帮助!
    • 因为它只是 HTTP 休息,所以你的客户端是什么并不重要......所以这听起来是一个不错的选择。很高兴我能帮助你。祝你好运!!
    【解决方案2】:

    啊,在对 stackoverflow 进行了更多搜索并与生成的代码进行比较后,它就可以工作了。

    错误:我缺少一个属性 IsActive,并且我没有将 Edm 属性添加到类及其属性中。

    对于遇到相同问题的任何人,请记住在所有属性上设置 EdmScalarProperty(或其他属性类型)属性,并且不要忘记设置哪个属性充当 EntityKey(例如 ID)。

    这就是我的Employee 课程现在的样子,而且它有效。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.Data.Objects.DataClasses;
    using System.Runtime.Serialization;
    
    [assembly: EdmSchemaAttribute()]
    namespace DtcInvoicerDbModel
    {
        [EdmEntityType(NamespaceName="DtcInvoicerDbModel", Name="Employee")]
        [DataContract(IsReference=true)]
        public class Employee
        {
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = true, IsNullable = false)]
            public int ID { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = false)]
            public bool IsActive { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = false)]
            public string FirstName { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = false)]
            public string LastName { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = false)]
            public string Username { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = false)]
            public string Password { get; set; }
    
            [DataMember]
            [EdmScalarProperty(EntityKeyProperty = false, IsNullable = true)]
            public DateTime? EmployeeSince { get; set; }
        }
    }
    

    【讨论】:

    • 很高兴看到你成功了......但我想我会采取戴夫的方法:)
    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 2016-07-18
    • 2019-12-23
    • 2014-06-15
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    相关资源
    最近更新 更多