【发布时间】: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