Служба данных OData / WCF не работает со сложным типом - PullRequest
3 голосов
/ 11 августа 2011

Я новичок в службах данных OData и WCF, так что это может быть легкой проблемой. Я использую VS Web Developer Express 2010, где у меня есть очень простая служба данных WCF, размещенная в консольном приложении. Он возвращает коллекцию IQuerable простого класса «Study» из хранилища (расположенного в отдельном проекте dll), который, в свою очередь, извлекает классы «Study» из проекта db в другой dll (таким образом, 3 проекта в решении).

У меня также есть класс «Эксперимент» в проекте БД, и в исследовании может быть несколько экспериментов. Когда я исключаю класс Experiment из Study, все работает, и я получаю данные, возвращающиеся. Проблема возникает, когда я добавляю коллекцию List в класс Study, а затем я получаю ошибку во время выполнения, когда пытаюсь запустить службу. В Firebug ошибка «500 Internal Server Error», а сообщение в браузере - «Ошибка запроса». Сервер обнаружил ошибку при обработке запроса. Смотрите подробности в журналах сервера. '

У меня есть IIS 7, и я также только что установил IIS 7.5, но, опять же, он совершенно новый для меня, поэтому я не могу понять, где размещен сервис или где просматривать журналы сервера / сети. В «C: \ inetpub \ logs \ LogFiles \ W3SVC1» видны только журналы IIS 7. Веб-сервер VS (Cassini) не запускается при запуске приложения, поэтому предполагается, что оно размещено в IIS 7.5 (?).

So
я могу вернуть дочерние классы / сложные объекты?
- как мне узнать, где размещен мой сервис и где я могу найти журналы сервера?

Вот главное приложение:

using MyStudyRepository;
using MyStudyDB;

namespace MyStudyService
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string serviceAddress = "http://localhost:998";
            Uri[] uriArray = { new Uri(serviceAddress) };
            Type serviceType = typeof(StudyDataService);

            using (var host = new DataServiceHost(serviceType,uriArray))
            {
                host.Open();
                Console.WriteLine("Press any key to stop service");
                Console.ReadKey();
            }
        }
    }

    public class StudyDataService : DataService<StudyRepository>
    {
        public static void InitializeService(IDataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
        }
    }
}

Вот хранилище:

using MyStudyDB;

namespace MyStudyRepository
{
    public class StudyRepository
    {
        List<Study> _List = new List<Study>();

        //Add constructor to populate myStudies list on creation of class
        public StudyRepository()
        {
            for (int i = 1; i < 5; i++)
            {
                Study myStudy = new Study() { ID = i, StudyOwnerId = i, StudyName = "Study" + i.ToString() /*, Experiments = null */ };
                _List.Add(myStudy);
            }
        }

        public IQueryable<Study> Studies
        {
            get
            {
                return _List.AsQueryable<Study>();
            }
        }
    }
}

А вот и БД:

namespace MyStudyDB
{
    public class Study
    {
        public int ID { get; set;}
        public int StudyOwnerId { get; set; }
        public string StudyName { get; set; }
        //public List<Experiment> Experiments { get; set; }
    }

    public class Experiment
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int StudyId { get; set; }
    }
}

Ответы [ 2 ]

5 голосов
/ 11 августа 2011

Для отладки службы данных WCF, пожалуйста, обратитесь к этому сообщению в блоге: http://blogs.msdn.com/b/phaniraj/archive/2008/06/18/debugging-ado-net-data-services.aspx Относительно того, почему коллекция Experiment не работает, есть две причины:

  • The Experimentкласс не распознается как тип сущности, потому что для него не установлено сущности.(Набор сущностей - это свойство IQueryable в вашем классе репозитория, которого у вас нет).В результате класс Experiment распознается только как сложный тип.
  • В настоящее время выпущенная версия служб данных WCF не поддерживает MultiValues, MultiValue фактически представляет собой набор примитивных или сложных типов.

Итак, у вас есть два способа это исправить.Либо убедитесь, что Experiment фактически является сущностью, добавив свойство IQueryable в свой класс репозитория.Или используйте последнюю версию CTP (http://blogs.msdn.com/b/astoriateam/archive/2011/06/30/announcing-wcf-data-services-june-2011-ctp-for-net4-amp-sl4.aspx), которая поддерживает MultiValues.

1 голос
/ 04 июня 2012

Спасибо! И я предполагаю, что отсутствует класс DataServiceKey в классе следующим образом:

[DataServiceKey("ID")]
public class Study
{ 
    .....
} 
...