【问题标题】:SOAP UI throws connection exception for WCF Entity Framework projectSOAP UI 为 WCF 实体框架项目引发连接异常
【发布时间】:2019-11-17 18:20:17
【问题描述】:

我在下面添加了所有代码。此代码取自 Microsoft CRUD 教程,我正在尝试将这些服务用于 WCF 项目。

在 WCF 服务实现中,我有一个FindStudent() 方法。如果我注释掉以db.Entry 开头的代码的第二行,它会起作用并且我会收到响应。

我的要求是使用记录的所有信息以及导航属性注册来填充此方法的返回 Student 对象。当我尝试使用第二行 SOAP UI 时抛出错误

错误:java.net.SocketException:连接重置

请帮忙。

public Student FindStudent(int? id)
{
    var student = db.Students.Find(id);
    //db.Entry(student).Collection(s => s.Enrollments).Load(); 
    return student;
}

下面是注释掉第二行时的响应,Enrollments 为 NULL。但我需要填充这个字段。如何做到这一点?

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <FindStudentResponse xmlns="http://tempuri.org/">
         <FindStudentResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfServiceApp.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:EnrollmentDate>2005-09-01T00:00:00</a:EnrollmentDate>
            <a:Enrollments i:nil="true"/>
            <a:FirstMidName>RaviTeja</a:FirstMidName>
            <a:ID>1</a:ID>
            <a:LastName>Sunkavalli</a:LastName>
         </FindStudentResult>
      </FindStudentResponse>
   </s:Body>
</s:Envelope>

模型类:

namespace WcfServiceApp.Models
{
    [DataContract]
    public class Student
    {
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public string FirstMidName { get; set; }
        //public string emailAddress { get; set; }
        [DataMember]
        public DateTime EnrollmentDate { get; set; }
        [DataMember]
        public List<Enrollment> Enrollments { get; set; }
    }

    [DataContract]
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [DataMember]
        public int CourseID { get; set; }
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public int Credits { get; set; }
        [DataMember]
        public List<Enrollment> Enrollments { get; set; }
    }

    [DataContract]
    public enum Grade
    {
        A, B, C, D, F
    }

    [DataContract]
    public class Enrollment
    {
        [DataMember]
        public int EnrollmentID { get; set; }
        [DataMember]
        public int CourseID { get; set; }
        [DataMember]
        public int StudentID { get; set; }
        [DataMember]
        public Grade? Grade { get; set; }
        [DataMember]
        public Course Course { get; set; }
        [DataMember]
        public Student Student { get; set; }
    }

    [DataContract]
    public class EnrollmentDateGroup
    {
        [DataType(DataType.Date)]
        [DataMember]
        public DateTime? EnrollmentDate { get; set; }
        [DataMember]
        public int StudentCount { get; set; }
    }
}

下面是WCF接口和服务:

namespace WcfServiceApp
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        List<EnrollmentDateGroup> GetStudentForHome();

        [OperationContract]
        IEnumerable<Student> GetStudents();

        [OperationContract]
        Student FindStudent(int? id);

        [OperationContract]
        Boolean SaveStudent(Student student);

        [OperationContract]
        Boolean DeleteStudent(int id);
    }
}

实施:

namespace WcfServiceApp
{
    public class MyService : IMyService
    {
        private SchoolContext db = new SchoolContext();

        public List<EnrollmentDateGroup> GetStudentForHome()
        {
            IQueryable<EnrollmentDateGroup> data = from student in db.Students
                                                   group student by student.EnrollmentDate into dateGroup
                                                   select new EnrollmentDateGroup()
                                                              { 
                                                                  EnrollmentDate = dateGroup.Key,
                                                                  StudentCount = dateGroup.Count()
                                                              };
            return data.ToList();
        }

        public IEnumerable<Student> GetStudents()
        {
            var students =  from s in db.Students select s;
            // db.Entry(student).Reference(s=>s.Enrollments).L
            //return students.ToList();
            return students;
        }

        public Student FindStudent(int? id)
        {
            var student = db.Students.Find(id);
            //db.Entry(student).Collection(s => s.Enrollments).Load();  -->Without this line I get //response but that property in return response from service is null. I want this property list in my //response. How to do that?
            return student;
        }

        public Boolean SaveStudent(Student student)
        {
            db.Students.Add(student);
            db.SaveChanges();
            return true;
        }

        public Boolean DeleteStudent(int id)
        {
            Student student = db.Students.Find(id);
            db.Students.Remove(student);
            db.SaveChanges();
            return true;
        }
    }
}

下面是我的 DbContext 类,我使用的是 EF6 和初始化程序。

namespace WcfServiceApp.DAL
{
    public class SchoolContext : DbContext
    {
        public SchoolContext() : base("SchoolContext")
        {
            Configuration.LazyLoadingEnabled = false;
            Console.WriteLine("called school context constructor");
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }

    public class SchoolInitializer: System.Data.Entity.DropCreateDatabaseIfModelChanges<SchoolContext>
    {
        protected override void Seed(SchoolContext context)
        {
            var students = new List<Student>
            {
            new Student{FirstMidName="RaviTeja",LastName="Sunkavalli",EnrollmentDate=DateTime.Parse("2005-09-01")},
            new Student{FirstMidName="SaiKrishna",LastName="Nadimpalli",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="SudeepReddy",LastName="Panyam",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Meha",LastName="Patel",EnrollmentDate=DateTime.Parse("2019-09-01")},
            new Student{FirstMidName="Venkatesh",LastName="Moturi",EnrollmentDate=DateTime.Parse("2019-09-01")},
            new Student{FirstMidName="Teja",LastName="Duggirala",EnrollmentDate=DateTime.Parse("2019-09-01")},
            new Student{FirstMidName="Ashwanth",LastName="Pullalakonda",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Himesh",LastName="Annam",EnrollmentDate=DateTime.Parse("2005-09-01")}
            };

            students.ForEach(s => context.Students.Add(s));
            context.SaveChanges();
            Console.WriteLine("saved student base data");

            var courses = new List<Course>
            {
            new Course{CourseID=1050,Title="Chemistry",Credits=3,},
            new Course{CourseID=4022,Title="Microeconomics",Credits=3,},
            new Course{CourseID=4041,Title="Macroeconomics",Credits=3,},
            new Course{CourseID=1045,Title="Calculus",Credits=4,},
            new Course{CourseID=3141,Title="Trigonometry",Credits=4,},
            new Course{CourseID=2021,Title="Composition",Credits=3,},
            new Course{CourseID=2042,Title="Literature",Credits=4,}
            };

            courses.ForEach(s => context.Courses.Add(s));
            context.SaveChanges();

            var enrollments = new List<Enrollment>
            {
            new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
            new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
            new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
            new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
            new Enrollment{StudentID=3,CourseID=1050},
            new Enrollment{StudentID=4,CourseID=1050,},
            new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
            new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
            new Enrollment{StudentID=6,CourseID=1045},
            new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
            };

            enrollments.ForEach(s => context.Enrollments.Add(s));
            context.SaveChanges();

            Console.WriteLine("saved enrollments base data");
        }
    }
}

【问题讨论】:

  • 可能是序列化程序中的循环引用问题。

标签: c# wcf entity-framework-6 wcf-binding


【解决方案1】:

问题似乎是代理生成序列化问题。尝试在您的 dbcontext 中禁用代理生成。如果异常消失,那么您可以使用 DTO 或使用 ProxyDataContractResolver。 如何配置Custom Data Contract Resolver

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2016-06-18
    • 2016-05-07
    • 2013-07-10
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2014-08-30
    相关资源
    最近更新 更多