Что я делаю неправильно? wcf & entity-framework - PullRequest
4 голосов
/ 25 августа 2011

Я только что наткнулся на WCF сегодня и начал изучать это.Однако, как только я попытался объединить его с EntityFramework, он перестал работать.Я создал модель сущности для своей базы данных dtcinvoicerdb, отключил генерацию кода и сам написал классы Entity/ObjectContext.Служба должна извлекать все Employees из базы данных.

Все работает нормально, проект компилируется и открывается WcfTestClient, но когда я пытаюсь вызвать операцию GetEmployees(), я получаю следующее исключение:

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

Я знаю, что много кода ниже, но все это довольно просто, так что терпите меня.

свойства изображения и модели 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();
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 25 августа 2011

Я знаю, что это не отвечает на ваш вопрос, но с вашим сервисом вы рассматривали возможность использования 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;
    }
}

После этого вы сможете получить доступ к своим сотрудникам с помощью запроса GET, используя URL-адрес:

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

Опять же, не ответ на ваш вопрос, но, возможно, альтернатива.Просто подумал, что добавлю это.

Надеюсь, это поможет!

2 голосов
/ 25 августа 2011

Ааа заставил его работать после еще одного поиска в стеке и сравнения с сгенерированным кодом.

Ошибки: Мне не хватало свойства 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; }
    }
}
...