Codefirst 问题 返回
如何设置建表字段默认可以为null除了主键,其他不为null的根据 IsNullable = false 来判断
[SugarColumn(ColumnDescription = "作者名", Length = 20, IsNullable = false)]
public string AuthorName { get; set; }
热忱回答(21)
-
fate sta VIP02023/6/6
var
db =
new
SqlSugarClient(
new
ConnectionConfig()
{
DbType = SqlSugar.DbType.SqlServer,
ConnectionString = Config.ConnectionString,
IsAutoCloseConnection =
true
,
ConfigureExternalServices =
new
ConfigureExternalServices
{
//注意: 这儿AOP设置不能少
EntityService = (c, p) =>
{
/***高版C#写法***/
//支持string?和string
if
(p.IsPrimarykey==
false
&&
new
NullabilityInfoContext()
.Create(c).WriteState
is
NullabilityState.Nullable)
{
//p.IsNullable = true;
}
}
}
});
0 回复 -
fate sta VIP02023/6/6
string? int?这种类型就是 isnullable=true
0 回复 -
字母搬运工 VIP02023/6/6
我就是不想用这种,这样改的地方太多了,因为不为null 的字段是比价少的,
0 回复 -
字母搬运工 VIP02023/6/6
或者在 EntityService 方法里面我怎么能读取到这个属性的值也可以的
0 回复 -
fate sta VIP02023/6/6
你这个没用的默认就是false
0 回复 -
fate sta VIP02023/6/61234567891011121314151617
EntityService = (c, p) =>
{
if
(p.IsPrimarykey==
true
)
//主键不能为null
{
p.IsNullable =
false
;
}
else
if
(特殊逻辑)
{
p.IsNullable =
false
;
}
else
//则否默认为null
{
p.IsNullable =
true
;
}
}
0 回复 -
fate sta VIP02023/6/6
你可以这样自这个写逻辑,或者自定义特性
0 回复 -
字母搬运工 VIP02023/6/7
这样感觉很奇怪
[SugarTable("articleCategory", "文章目录")]
public class ArticleCategory
{
/// <summary>
/// 目录id
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "Category_id")]
public int CategoryId { get; set; }
[SugarColumn(ColumnDescription = "目录名", IsNullable = true, Length = 20)]
public string Name { get; set; }
public int? ParentId { get; set; }
[SugarColumn(ColumnDescription = "创建时间", ColumnName = "create_time")]
public DateTime? CreateTime { get; set; }
}
123456789101112if
(p.IsPrimarykey ==
true
)
//主键不能为null
{
p.IsNullable =
false
;
}
else
if
(p.IsNullable ==
true
)
{
p.IsNullable =
false
;
}
else
//则否默认为null
{
p.IsNullable =
true
;
}
0 回复 -
fate sta VIP02023/6/7
@字母搬运工:这样不好,你可以自定义一个特性比如[Required]
0 回复 -
fate sta VIP02023/6/7
我加了一个扩展属性来解决你这个需求
0 回复 -
fate sta VIP02023/6/7
SqlSugarCoreNoDrive 5.1.4.84-preview01
加了个扩展属性
12[SqlSugar.SugarColumn(ExtendedAttribute =你的类.NUll变量)]
public
string
Name {
get
;
set
; }
你AOP根据这个属性来处理就行了
0 回复 -
fate sta VIP02023/6/7
if
(p.ExtendedAttribute?.ToString()==你的类.Null变量
)
//object类型要ToString
{
p.IsNullable =
false
;
}
0 回复 -
字母搬运工 VIP02023/6/7
还有个问题,如果不想写 ColumnDescription ,可否直接读取 XML的值
项目是有 XML文件
0 回复 -
fate sta VIP02023/6/7
@字母搬运工:可以的 只要你发布出来
0 回复 -
字母搬运工 VIP02023/6/7
发布出来,那不就是部署后才能么,是不是有风险。一般使用codeFirst是在开发中使用吧。
可不可以这样,配置xml路径,在加个方法读取
0 回复 -
fate sta VIP02023/6/7
@字母搬运工:开发中也可以的要在bin目录里面有才行
0 回复 -
fate sta VIP02023/6/7
你需要把xml生成的dll同目录下面 ,启动项目
0 回复 -
字母搬运工 VIP02023/6/7
我知道了,我没放到同目录, 放到api层了
0 回复 -
字母搬运工 VIP02023/6/8
好像还是获取不到,找了个方法,加载所有的xml文件,或者指定的xml文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375using
System;
using
System.Collections.Generic;
using
System.IO;
using
System.Linq;
using
System.Reflection;
using
System.Text;
using
System.Text.RegularExpressions;
using
System.Threading.Tasks;
using
System.Xml.XPath;
namespace
Infrastructure.Helper
{
public
class
XmlCommentHelper
{
private
static
Regex RefTagPattern =
new
Regex(
@"<(see|paramref) (name|cref)=""([TPF]{1}:)?(?<display>.+?)"" ?/>"
);
private
static
Regex CodeTagPattern =
new
Regex(
@"<c>(?<display>.+?)</c>"
);
private
static
Regex ParaTagPattern =
new
Regex(
@"<para>(?<display>.+?)</para>"
, RegexOptions.Singleline);
List<XPathNavigator> navigators =
new
List<XPathNavigator>();
/// <summary>
/// 从当前dll文件中加载所有的xml文件
/// </summary>
public
void
LoadAll()
{
var
files = Directory.GetFiles(Directory.GetCurrentDirectory());
foreach
(
var
file
in
files)
{
if
(
string
.Equals(Path.GetExtension(file),
".xml"
, StringComparison.OrdinalIgnoreCase))
{
Load(file);
}
}
}
/// <summary>
/// 从xml中加载
/// </summary>
/// <param name="xmls"></param>
public
void
LoadXml(
params
string
[] xmls)
{
foreach
(
var
xml
in
xmls)
{
Load(
new
MemoryStream(Encoding.UTF8.GetBytes(xml)));
}
}
/// <summary>
/// 从文件中加载
/// </summary>
/// <param name="xmlFiles"></param>
public
void
Load(
params
string
[] xmlFiles)
{
foreach
(
var
xmlFile
in
xmlFiles)
{
var
doc =
new
XPathDocument(xmlFile);
navigators.Add(doc.CreateNavigator());
//Console.WriteLine("加载xml文件=" + xmlFile);
}
}
/// <summary>
/// 从流中加载
/// </summary>
/// <param name="streams"></param>
public
void
Load(
params
Stream[] streams)
{
foreach
(
var
stream
in
streams)
{
var
doc =
new
XPathDocument(stream);
navigators.Add(doc.CreateNavigator());
}
}
/// <summary>
/// 读取类型中的注释
/// </summary>
/// <param name="type">类型</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetTypeComment(Type type,
string
xPath =
"summary"
,
bool
humanize =
true
)
{
var
typeMemberName = GetMemberNameForType(type);
return
GetComment(typeMemberName, xPath, humanize);
}
/// <summary>
/// 读取字段或者属性的注释
/// </summary>
/// <param name="fieldOrPropertyInfo">字段或者属性</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetFieldOrPropertyComment(MemberInfo fieldOrPropertyInfo,
string
xPath =
"summary"
,
bool
humanize =
true
)
{
var
fieldOrPropertyMemberName = GetMemberNameForFieldOrProperty(fieldOrPropertyInfo);
return
GetComment(fieldOrPropertyMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetMethodComment(MethodInfo methodInfo,
string
xPath =
"summary"
,
bool
humanize =
true
)
{
var
methodMemberName = GetMemberNameForMethod(methodInfo);
return
GetComment(methodMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的返回值注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetMethodReturnComment(MethodInfo methodInfo,
bool
humanize =
true
)
{
return
GetMethodComment(methodInfo,
"returns"
, humanize);
}
/// <summary>
/// 读取参数的注释
/// </summary>
/// <param name="parameterInfo">参数</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetParameterComment(ParameterInfo parameterInfo,
bool
humanize =
true
)
{
if
(!(parameterInfo.Member
is
MethodInfo methodInfo))
return
string
.Empty;
var
methodMemberName = GetMemberNameForMethod(methodInfo);
return
GetComment(methodMemberName, $
"param[@name='{parameterInfo.Name}']"
, humanize);
}
/// <summary>
/// 读取方法的所有参数的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
Dictionary<
string
,
string
> GetParameterComments(MethodInfo methodInfo,
bool
humanize =
true
)
{
var
parameterInfos = methodInfo.GetParameters();
Dictionary<
string
,
string
> dict =
new
Dictionary<
string
,
string
>();
foreach
(
var
parameterInfo
in
parameterInfos)
{
dict[parameterInfo.Name] = GetParameterComment(parameterInfo, humanize);
}
return
dict;
}
/// <summary>
/// 读取指定名称节点的注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetComment(
string
name,
string
xPath,
bool
humanize =
true
)
{
foreach
(
var
_xmlNavigator
in
navigators)
{
var
typeSummaryNode = _xmlNavigator.SelectSingleNode($
"/doc/members/member[@name='{name}']/{xPath.Trim('/', '\\')}"
);
if
(typeSummaryNode !=
null
)
{
return
humanize ? Humanize(typeSummaryNode.InnerXml) : typeSummaryNode.InnerXml;
}
}
return
string
.Empty;
}
/// <summary>
/// 读取指定节点的summary注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetSummary(
string
name,
bool
humanize =
true
)
{
return
GetComment(name,
"summary"
, humanize);
}
/// <summary>
/// 读取指定节点的example注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如:去掉xml标记)</param>
/// <returns></returns>
public
string
GetExample(
string
name,
bool
humanize =
true
)
{
return
GetComment(name,
"example"
, humanize);
}
/// <summary>
/// 获取方法的节点名称
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public
string
GetMemberNameForMethod(MethodInfo method)
{
var
builder =
new
StringBuilder(
"M:"
);
builder.Append(QualifiedNameFor(method.DeclaringType));
builder.Append($
".{method.Name}"
);
var
parameters = method.GetParameters();
if
(parameters.Any())
{
var
parametersNames = parameters.Select(p =>
{
return
p.ParameterType.IsGenericParameter
? $
"`{p.ParameterType.GenericParameterPosition}"
: QualifiedNameFor(p.ParameterType, expandGenericArgs:
true
);
});
builder.Append($
"({string.Join("
,
", parametersNames)})"
);
}
return
builder.ToString();
}
/// <summary>
/// 获取类型的节点名称
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public
string
GetMemberNameForType(Type type)
{
var
builder =
new
StringBuilder(
"T:"
);
builder.Append(QualifiedNameFor(type));
return
builder.ToString();
}
/// <summary>
/// 获取字段或者属性的节点名称
/// </summary>
/// <param name="fieldOrPropertyInfo"></param>
/// <returns></returns>
public
string
GetMemberNameForFieldOrProperty(MemberInfo fieldOrPropertyInfo)
{
var
builder =
new
StringBuilder(((fieldOrPropertyInfo.MemberType & MemberTypes.Field) != 0) ?
"F:"
:
"P:"
);
builder.Append(QualifiedNameFor(fieldOrPropertyInfo.DeclaringType));
builder.Append($
".{fieldOrPropertyInfo.Name}"
);
return
builder.ToString();
}
private
string
QualifiedNameFor(Type type,
bool
expandGenericArgs =
false
)
{
if
(type.IsArray)
return
$
"{QualifiedNameFor(type.GetElementType(), expandGenericArgs)}[]"
;
var
builder =
new
StringBuilder();
if
(!
string
.IsNullOrEmpty(type.Namespace))
builder.Append($
"{type.Namespace}."
);
if
(type.IsNested)
{
builder.Append($
"{string.Join("
.
", GetNestedTypeNames(type))}."
);
}
if
(type.IsConstructedGenericType && expandGenericArgs)
{
var
nameSansGenericArgs = type.Name.Split(
'`'
).First();
builder.Append(nameSansGenericArgs);
var
genericArgsNames = type.GetGenericArguments().Select(t =>
{
return
t.IsGenericParameter
? $
"`{t.GenericParameterPosition}"
: QualifiedNameFor(t,
true
);
});
builder.Append($
"{{{string.Join("
,
", genericArgsNames)}}}"
);
}
else
{
builder.Append(type.Name);
}
return
builder.ToString();
}
private
IEnumerable<
string
> GetNestedTypeNames(Type type)
{
if
(!type.IsNested || type.DeclaringType ==
null
) yield
break
;
foreach
(
var
nestedTypeName
in
GetNestedTypeNames(type.DeclaringType))
{
yield
return
nestedTypeName;
}
yield
return
type.DeclaringType.Name;
}
private
string
Humanize(
string
text)
{
if
(text ==
null
)
throw
new
ArgumentNullException(
"text"
);
//Call DecodeXml at last to avoid entities like < and > to break valid xml
text = NormalizeIndentation(text);
text = HumanizeRefTags(text);
text = HumanizeCodeTags(text);
text = HumanizeParaTags(text);
text = DecodeXml(text);
return
text;
}
private
string
NormalizeIndentation(
string
text)
{
string
[] lines = text.Split(
'\n'
);
string
padding = GetCommonLeadingWhitespace(lines);
int
padLen = padding ==
null
? 0 : padding.Length;
// remove leading padding from each line
for
(
int
i = 0, l = lines.Length; i < l; ++i)
{
string
line = lines[i].TrimEnd(
'\r'
);
// remove trailing '\r'
if
(padLen != 0 && line.Length >= padLen && line.Substring(0, padLen) == padding)
line = line.Substring(padLen);
lines[i] = line;
}
// remove leading empty lines, but not all leading padding
// remove all trailing whitespace, regardless
return
string
.Join(
"\r\n"
, lines.SkipWhile(x =>
string
.IsNullOrWhiteSpace(x))).TrimEnd();
}
private
string
GetCommonLeadingWhitespace(
string
[] lines)
{
if
(
null
== lines)
throw
new
ArgumentException(
"lines"
);
if
(lines.Length == 0)
return
null
;
string
[] nonEmptyLines = lines
.Where(x => !
string
.IsNullOrWhiteSpace(x))
.ToArray();
if
(nonEmptyLines.Length < 1)
return
null
;
int
padLen = 0;
// use the first line as a seed, and see what is shared over all nonEmptyLines
string
seed = nonEmptyLines[0];
for
(
int
i = 0, l = seed.Length; i < l; ++i)
{
if
(!
char
.IsWhiteSpace(seed, i))
break
;
if
(nonEmptyLines.Any(line => line[i] != seed[i]))
break
;
++padLen;
}
if
(padLen > 0)
return
seed.Substring(0, padLen);
return
null
;
}
private
string
HumanizeRefTags(
string
text)
{
return
RefTagPattern.Replace(text, (match) => match.Groups[
"display"
].Value);
}
private
string
HumanizeCodeTags(
string
text)
{
return
CodeTagPattern.Replace(text, (match) =>
"{"
+ match.Groups[
"display"
].Value +
"}"
);
}
private
string
HumanizeParaTags(
string
text)
{
return
ParaTagPattern.Replace(text, (match) =>
"<br>"
+ match.Groups[
"display"
].Value);
}
private
string
DecodeXml(
string
text)
{
return
System.Net.WebUtility.HtmlDecode(text);
}
}
}
0 回复 -
fate sta VIP02023/6/8
@字母搬运工:正常是能获取到的
0 回复 -
fate sta VIP02023/6/8
你可以写个可以重现的DEMO 空的API
0 回复