如何在 EF 6 的 Ado net 中将 table 实体添加为可序列化
How to add table entity as serializable in Ado net in EF 6
我是Ado net的新手。我正在使用 EF 6。
我有 2 个 table UserInfo 和 UserType。
现在,当我想要获取 userInfo 时,我想将 UserTypeName 设置为与其他 UserInfo 一起显示在网格中,为此我使用了以下代码。
public List<UserInfoBind> SearchBindUser(UserInfo objSeacrh)
{
try
{
List<UserInfoBind> objList = (from sql in dbContext.UserInfoes.Where(t => t.IsDelete != true)
join tblType in dbContext.UserTypes
on sql.UserType equals tblType.UserTypeID
select new UserInfoBind()
{
UserTypeName = tblType.UserTypeName
}).ToList();
return objList;
}
catch (Exception ex)
{
throw ex;
}
}
和 Decalre UserInforBind 如下:
[DataContract]
public class UserInfoBind : UserInfo
{
public UserInfoBind()
{
}
[DataMember]
public string UserTypeName { get; set; }
}
但它给出错误:“类型 'DAL.UserInfoBind' 无法继承自未标记为 DataContractAttribute 或 SerializableAttribute 的类型。”
那么如何在 EF 6 中创建 Userinfo table 实体的 SerializableAttribute。
谢谢,
Hitesh Paghadal
有两种方法可以达到你想要的效果。
如果您也想使用用于表示 WCF DataContract 数据库模型的相同类型,则需要使用 DataContract 属性标记您的实体,使用 DataMember 属性标记属性。我假设您使用的是数据库优先方法,如果是,您可以更改代码生成模板以使用 DataContract 属性标记所有实体,并使用 DataMember 属性标记所有属性。
另一种方法是让您的数据库类型保持原样,并为您的 DataContract 创建一组新的类型,并使用 AutoMapper 等工具来映射您需要的属性。
我更喜欢第二种方法,因为它允许您更改基础模型而不影响通过 WCF 服务公开的内容。
编辑:如果您想编辑代码模板,请按以下步骤操作
在您的 EDMX 文件下,您将看到两个扩展名为 .tt 的文件。一个用于数据上下文,一个用于模型。
打开为模型创建的模型并进行以下更改
// To add DataMember attibute in all the properties
// Change
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
// To
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"[DataMember] {0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
// To add DataMember attibute in all the navigation properties
// Change
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
// TO
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"[DataMember] {0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
// To add DataContract attibute in all the types
// Change
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
// To
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"[DataContract] {0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
// To include System.Runtime.Serialization
// Change
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
// To
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"using System.Runtime.Serialization;{2}" +
"{3}",
inHeader ? Environment.NewLine : "",
Environment.NewLine,
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
编辑 2:更改您的 select 方法以包含 UserInfo 中的所有属性,否则您的 UserInfoBind 将只有 UserTypeName
select new UserInfoBind()
{
userInfoprop1 = sql.value1,
userInfoprop2 = sql.value2,
UserTypeName = tblType.UserTypeName
}).ToList();
我是Ado net的新手。我正在使用 EF 6。
我有 2 个 table UserInfo 和 UserType。
现在,当我想要获取 userInfo 时,我想将 UserTypeName 设置为与其他 UserInfo 一起显示在网格中,为此我使用了以下代码。
public List<UserInfoBind> SearchBindUser(UserInfo objSeacrh)
{
try
{
List<UserInfoBind> objList = (from sql in dbContext.UserInfoes.Where(t => t.IsDelete != true)
join tblType in dbContext.UserTypes
on sql.UserType equals tblType.UserTypeID
select new UserInfoBind()
{
UserTypeName = tblType.UserTypeName
}).ToList();
return objList;
}
catch (Exception ex)
{
throw ex;
}
}
和 Decalre UserInforBind 如下:
[DataContract]
public class UserInfoBind : UserInfo
{
public UserInfoBind()
{
}
[DataMember]
public string UserTypeName { get; set; }
}
但它给出错误:“类型 'DAL.UserInfoBind' 无法继承自未标记为 DataContractAttribute 或 SerializableAttribute 的类型。”
那么如何在 EF 6 中创建 Userinfo table 实体的 SerializableAttribute。 谢谢, Hitesh Paghadal
有两种方法可以达到你想要的效果。
如果您也想使用用于表示 WCF DataContract 数据库模型的相同类型,则需要使用 DataContract 属性标记您的实体,使用 DataMember 属性标记属性。我假设您使用的是数据库优先方法,如果是,您可以更改代码生成模板以使用 DataContract 属性标记所有实体,并使用 DataMember 属性标记所有属性。
另一种方法是让您的数据库类型保持原样,并为您的 DataContract 创建一组新的类型,并使用 AutoMapper 等工具来映射您需要的属性。
我更喜欢第二种方法,因为它允许您更改基础模型而不影响通过 WCF 服务公开的内容。
编辑:如果您想编辑代码模板,请按以下步骤操作
在您的 EDMX 文件下,您将看到两个扩展名为 .tt 的文件。一个用于数据上下文,一个用于模型。 打开为模型创建的模型并进行以下更改
// To add DataMember attibute in all the properties
// Change
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
// To
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"[DataMember] {0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
// To add DataMember attibute in all the navigation properties
// Change
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
// TO
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"[DataMember] {0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
// To add DataContract attibute in all the types
// Change
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
// To
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"[DataContract] {0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
// To include System.Runtime.Serialization
// Change
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
// To
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"using System.Runtime.Serialization;{2}" +
"{3}",
inHeader ? Environment.NewLine : "",
Environment.NewLine,
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
编辑 2:更改您的 select 方法以包含 UserInfo 中的所有属性,否则您的 UserInfoBind 将只有 UserTypeName
select new UserInfoBind()
{
userInfoprop1 = sql.value1,
userInfoprop2 = sql.value2,
UserTypeName = tblType.UserTypeName
}).ToList();