VS2017,具有 WCF/EF 的 C# nTier,无法使用来自 EF6 Entify 的行的 IList 实例化返回的对象
VS2017, C# nTier with WCF/EF, cannot instantiate returned obj with IList of rows from EF6 Entify
我正在使用 UI、服务、逻辑、业务数据和数据层项目构建 VS C# 5 层解决方案。我正在使用 WCF 和 EF6,EF6 加载到 UI、服务和数据层。我正在为数据层中的实体使用 ADO.NET,并且我的实体构建为数据库优先。
我的 UI Win-Form 上有一个 DataGridView 控件,我想按需在 DataGridView 中查看我组织的所有或 select 成员。
当我在 UI 中实例化我的服务时,我的代码用于将请求的数据行从数据层(EF 查询)返回到 return,通过逻辑层返回到服务层.
但是当我尝试使用服务层的 returned 对象时,我收到 "Object reference not set to an instance of an object" 错误。
我的目标是使用 returned 列表作为我的 DataGridView 的绑定源控件的数据源。我还需要帮助来了解如何让 I-List 对象公开到其对象级别。如有任何帮助,我们将不胜感激。
** Service Contract: **
***
[DataContract]
public class MemberList
{
[DataMember]
public IList MembersInList { get; set; }
}
***
[DataContract]
public class Member
{
[DataMember]
public int MemberID { get; set; }
[DataMember ]
public string Last_Name { get; set; }
[DataMember]
public string First_Name { get; set; }
[DataMember]
public string MidInit { get; set; }
[DataMember]
public string Email_Address { get; set; }
}
***
** Here's my datalayer: **
***
public MemberBDOList FillMemberGrid()
{
MemberBDOList myDAO = new MemberBDOList();
using (var afDBEntities = new AFDBEntities())
{
var members = afDBEntities.Members.ToList(); // gets all 68 Members in MSSQL table
if (members != null)
{
myDAO.MembersBDOInList = members;
}
}
return myDAO as MemberBDOList; //returns all 68 Members to Logic Layer as collection
}
***
** Here's my Service.cs object (Service layer): **
***
public MemberList FillMemberGrid()
{
MemberBDOList objMembersBDO = null;
try
{
objMembersBDO = new MemberBDOList();
objMembersBDO = memberLogic.FillMemberGrid();
}
catch (Exception e)
{
var msg = e.Message;
var reason = "FillMemberGrid Exception";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
if (objMembersBDO.MembersBDOInList == null)
{
var msg = string.Format("No members were found.");
var reason = "FillMemberGrid: Empty Entity Member";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
var objMembers = new MemberList();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); // method below
return objMembers.MembersInList as MemberList;
}
private void TranslateMembersBDOToMembersDTO(MemberBDOList objMembersBDO, MemberList objMembers)
{
objMembers.MembersInList = objMembersBDO.MembersBDOInList;
}
}
***
** Here is the Business-Data object: **
***
[Serializable]
public class MemberBDOList
{
public IList MembersBDOInList { get; set; }
}
***
** And here are the UI methods: **
***
MemberServiceProxy.Member member;
MemberServiceProxy.MemberList memberList;
private void btnFillMemberGrid_Click(object sender, EventArgs e)
{
BindingSource bSrc = new BindingSource();
int M = 0;
try
{
M = 1;
memberList = GetMemberList();
M = 3;
//fails here with "Object reference not set to an instance of an object."
bSrc.DataSource = memberList.MembersInList.ToList(); // fails with or without To-List
M = 5;
adgView.DataSource = bSrc;
M = 7;
adgView.Refresh();
}
catch (Exception ex)
{
}
}
private MemberList GetMemberList()
{
var results = new MemberList();
int M = 0;
try
{
M = 1;
var client = new MemberServiceClient();
M = 3;
//go get the member list from Data Layer EF
results = client.FillMemberGrid();
return results;
}
catch (Exception ex)
{
return results;
}
}
***
** 数据层和服务层中的代码更新 - 在 List 的数据成员级别转换 DataContract "Members" 对象。此处显示 DAL 层。 **
***
public MembersBDO FillMemberGrid()
{
var membersBDO = new MembersBDO();
var memberBDO = new MemberBDO();
int M = 0;
try
{
M = 1;
using (var afDBEntities = new ACTSFactsDBEntities())
{
M = 3;
var members = afDBEntities.Members.ToList(); // gets all 68 Members in MSSQL table (Entity is Database-first)
M = 5;
// if (members != null)
// {
// M = 7;
// membersBDO.MemberBDOList = members; //this works with the IList data contract,
// //but the IList data, unconverted, belongs to the data layer - no conversion is done
// //here from DAL data types to BDO data types at the members[index].(columnName) level
// }
//so, (below) this solves that issue, and converts to the [DataMember] level (the data row's columns)
//for each [DataContract] Member in "members" - the List<Member> object which belongs to the data layer project.
//
M = 9;
if (members != null) //the data layer object has rows, good.
{
int n = 0;
foreach (Member m in members) //read through each data layer EF Member type in "members" list
{
memberBDO = new MemberBDO() //instantiate a new MemberBDO type to translate the DAL member.Columns to
{
MemberID = m.MemberID, //each DAL column must be translated to its matching BDO type
Last_Name = m.Last_Name,
First_Name = m.First_Name,
MidInit = m.MidInit,
Email_Address = m.Email_Address,
Home_Phone = m.Home_Phone,
Cell_Phone = m.Cell_Phone,
Mailing_Address = m.Mailing_Address, etc
};
membersBDO.memberBDOList.Add(memberBDO);
memberBDO = null;
n += 1;
if (n > 60) break; // my code breaks at request for all 68 rows with error
// - "MaxReceivedMessageSize" (65536 bytes) property exceeded
}
}
M = 11;
return membersBDO; //returning 61 of my 68 Members works to Service layer, through Logic Layer
}
}
***
** Service 层中的代码更改:**
***
public Members FillMemberGrid()
{
MembersBDO objMembersBDO = null;
try
{
objMembersBDO = new MembersBDO();
objMembersBDO = memberLogic.FillMemberGrid();
}
catch (Exception e)
{
var msg = e.Message;
var reason = "FillMemberGrid Exception";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
if (objMembersBDO == null)
{
var msg = string.Format("No members were found.");
var reason = "FillMemberGrid: Empty Entity Member";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
var objMembers = new Members();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); //a private method defined below
return objMembers as Members;
}
private void TranslateMembersBDOToMembersDTO(MembersBDO objMembersBDO, Members objMembers)
{
//objMembers.MemberList = objMembersBDO.MemberBDOList;
foreach (MemberBDO mBDO in objMembersBDO.memberBDOList)
{
Member m = new Member();
TranslateMemberBDOToMemberDTO(mBDO, m); //calling the same translate code that translates the return of a one member request
objMembers.MemberList.Add(m);
m = null;
m = new Member();
}
}
***
** IMemberService.cs 中对 [DataContract] 成员 class 的更改 **
***
[DataContract]
public class Members
{
[DataMember]
public List<Member> MemberList { get; set; } = new List<Member>();
}
***
** 这是业务领域对象层中 class MembersBDO 的更改 **
***
[Serializable]
public class MembersBDO
{
public List<MemberBDO> memberBDOList { get; set; } = new List<MemberBDO>();
}
***
您在 FillMemberGrid()
中的 return 语句是 returning null,因为您正试图将 IList
转换为 MemberList
,但这是行不通的。
var objMembers = new MemberList();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); // method below
return objMembers.MembersInList as MemberList;
objMembers
已经是成员列表。你为什么要 returning 它的 MembersInList as MemberList
?你应该 return objMembers
。
感谢 MBD 帮助解决我的问题。我们都需要一个共鸣板,你的建议让我走上了正确的轨道。请参阅我的更新以获取我最终在应用程序中使用的答案。仍然有问题,但不是这个。
我正在使用 UI、服务、逻辑、业务数据和数据层项目构建 VS C# 5 层解决方案。我正在使用 WCF 和 EF6,EF6 加载到 UI、服务和数据层。我正在为数据层中的实体使用 ADO.NET,并且我的实体构建为数据库优先。
我的 UI Win-Form 上有一个 DataGridView 控件,我想按需在 DataGridView 中查看我组织的所有或 select 成员。
当我在 UI 中实例化我的服务时,我的代码用于将请求的数据行从数据层(EF 查询)返回到 return,通过逻辑层返回到服务层.
但是当我尝试使用服务层的 returned 对象时,我收到 "Object reference not set to an instance of an object" 错误。
我的目标是使用 returned 列表作为我的 DataGridView 的绑定源控件的数据源。我还需要帮助来了解如何让 I-List 对象公开到其对象级别。如有任何帮助,我们将不胜感激。
** Service Contract: **
***
[DataContract]
public class MemberList
{
[DataMember]
public IList MembersInList { get; set; }
}
***
[DataContract]
public class Member
{
[DataMember]
public int MemberID { get; set; }
[DataMember ]
public string Last_Name { get; set; }
[DataMember]
public string First_Name { get; set; }
[DataMember]
public string MidInit { get; set; }
[DataMember]
public string Email_Address { get; set; }
}
***
** Here's my datalayer: **
***
public MemberBDOList FillMemberGrid()
{
MemberBDOList myDAO = new MemberBDOList();
using (var afDBEntities = new AFDBEntities())
{
var members = afDBEntities.Members.ToList(); // gets all 68 Members in MSSQL table
if (members != null)
{
myDAO.MembersBDOInList = members;
}
}
return myDAO as MemberBDOList; //returns all 68 Members to Logic Layer as collection
}
***
** Here's my Service.cs object (Service layer): **
***
public MemberList FillMemberGrid()
{
MemberBDOList objMembersBDO = null;
try
{
objMembersBDO = new MemberBDOList();
objMembersBDO = memberLogic.FillMemberGrid();
}
catch (Exception e)
{
var msg = e.Message;
var reason = "FillMemberGrid Exception";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
if (objMembersBDO.MembersBDOInList == null)
{
var msg = string.Format("No members were found.");
var reason = "FillMemberGrid: Empty Entity Member";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
var objMembers = new MemberList();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); // method below
return objMembers.MembersInList as MemberList;
}
private void TranslateMembersBDOToMembersDTO(MemberBDOList objMembersBDO, MemberList objMembers)
{
objMembers.MembersInList = objMembersBDO.MembersBDOInList;
}
}
***
** Here is the Business-Data object: **
***
[Serializable]
public class MemberBDOList
{
public IList MembersBDOInList { get; set; }
}
***
** And here are the UI methods: **
***
MemberServiceProxy.Member member;
MemberServiceProxy.MemberList memberList;
private void btnFillMemberGrid_Click(object sender, EventArgs e)
{
BindingSource bSrc = new BindingSource();
int M = 0;
try
{
M = 1;
memberList = GetMemberList();
M = 3;
//fails here with "Object reference not set to an instance of an object."
bSrc.DataSource = memberList.MembersInList.ToList(); // fails with or without To-List
M = 5;
adgView.DataSource = bSrc;
M = 7;
adgView.Refresh();
}
catch (Exception ex)
{
}
}
private MemberList GetMemberList()
{
var results = new MemberList();
int M = 0;
try
{
M = 1;
var client = new MemberServiceClient();
M = 3;
//go get the member list from Data Layer EF
results = client.FillMemberGrid();
return results;
}
catch (Exception ex)
{
return results;
}
}
***
** 数据层和服务层中的代码更新 - 在 List 的数据成员级别转换 DataContract "Members" 对象。此处显示 DAL 层。 **
***
public MembersBDO FillMemberGrid()
{
var membersBDO = new MembersBDO();
var memberBDO = new MemberBDO();
int M = 0;
try
{
M = 1;
using (var afDBEntities = new ACTSFactsDBEntities())
{
M = 3;
var members = afDBEntities.Members.ToList(); // gets all 68 Members in MSSQL table (Entity is Database-first)
M = 5;
// if (members != null)
// {
// M = 7;
// membersBDO.MemberBDOList = members; //this works with the IList data contract,
// //but the IList data, unconverted, belongs to the data layer - no conversion is done
// //here from DAL data types to BDO data types at the members[index].(columnName) level
// }
//so, (below) this solves that issue, and converts to the [DataMember] level (the data row's columns)
//for each [DataContract] Member in "members" - the List<Member> object which belongs to the data layer project.
//
M = 9;
if (members != null) //the data layer object has rows, good.
{
int n = 0;
foreach (Member m in members) //read through each data layer EF Member type in "members" list
{
memberBDO = new MemberBDO() //instantiate a new MemberBDO type to translate the DAL member.Columns to
{
MemberID = m.MemberID, //each DAL column must be translated to its matching BDO type
Last_Name = m.Last_Name,
First_Name = m.First_Name,
MidInit = m.MidInit,
Email_Address = m.Email_Address,
Home_Phone = m.Home_Phone,
Cell_Phone = m.Cell_Phone,
Mailing_Address = m.Mailing_Address, etc
};
membersBDO.memberBDOList.Add(memberBDO);
memberBDO = null;
n += 1;
if (n > 60) break; // my code breaks at request for all 68 rows with error
// - "MaxReceivedMessageSize" (65536 bytes) property exceeded
}
}
M = 11;
return membersBDO; //returning 61 of my 68 Members works to Service layer, through Logic Layer
}
}
***
** Service 层中的代码更改:**
***
public Members FillMemberGrid()
{
MembersBDO objMembersBDO = null;
try
{
objMembersBDO = new MembersBDO();
objMembersBDO = memberLogic.FillMemberGrid();
}
catch (Exception e)
{
var msg = e.Message;
var reason = "FillMemberGrid Exception";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
if (objMembersBDO == null)
{
var msg = string.Format("No members were found.");
var reason = "FillMemberGrid: Empty Entity Member";
throw new FaultException<MemberFault>(new MemberFault(msg), reason);
}
var objMembers = new Members();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); //a private method defined below
return objMembers as Members;
}
private void TranslateMembersBDOToMembersDTO(MembersBDO objMembersBDO, Members objMembers)
{
//objMembers.MemberList = objMembersBDO.MemberBDOList;
foreach (MemberBDO mBDO in objMembersBDO.memberBDOList)
{
Member m = new Member();
TranslateMemberBDOToMemberDTO(mBDO, m); //calling the same translate code that translates the return of a one member request
objMembers.MemberList.Add(m);
m = null;
m = new Member();
}
}
***
** IMemberService.cs 中对 [DataContract] 成员 class 的更改 **
***
[DataContract]
public class Members
{
[DataMember]
public List<Member> MemberList { get; set; } = new List<Member>();
}
***
** 这是业务领域对象层中 class MembersBDO 的更改 **
***
[Serializable]
public class MembersBDO
{
public List<MemberBDO> memberBDOList { get; set; } = new List<MemberBDO>();
}
***
您在 FillMemberGrid()
中的 return 语句是 returning null,因为您正试图将 IList
转换为 MemberList
,但这是行不通的。
var objMembers = new MemberList();
TranslateMembersBDOToMembersDTO(objMembersBDO, objMembers); // method below
return objMembers.MembersInList as MemberList;
objMembers
已经是成员列表。你为什么要 returning 它的 MembersInList as MemberList
?你应该 return objMembers
。
感谢 MBD 帮助解决我的问题。我们都需要一个共鸣板,你的建议让我走上了正确的轨道。请参阅我的更新以获取我最终在应用程序中使用的答案。仍然有问题,但不是这个。